Typescript 개체의 인덱싱된 멤버 유형을 적용하시겠습니까?
문자열 ->의 매핑을 Typescript 객체에 저장하고 모든 값이 문자열에 매핑되도록 합니다.예를 들어 다음과 같습니다.
var stuff = {};
stuff["a"] = "foo"; // okay
stuff["b"] = "bar"; // okay
stuff["c"] = false; // ERROR! bool != string
값이 문자열(또는 모든 유형)이어야 한다고 강제할 수 있는 방법이 있습니까?
var stuff: { [key: string]: string; } = {};
stuff['a'] = ''; // ok
stuff['a'] = 4; // error
// ... or, if you're using this a lot and don't want to type so much ...
interface StringMap { [key: string]: string; }
var stuff2: StringMap = { };
// same as above
interface AgeMap {
[name: string]: number
}
const friendsAges: AgeMap = {
"Sandy": 34,
"Joe": 28,
"Sarah": 30,
"Michelle": "fifty", // ERROR! Type 'string' is not assignable to type 'number'.
};
여기서 인터페이스는AgeMap는 키를 문자열로, 값을 숫자로 적용합니다.키워드name는 임의의 ID로 사용할 수 있으며 인터페이스 또는 유형의 구문을 제안하기 위해 사용해야 합니다.
동일한 구문을 사용하여 오브젝트에 유니언 유형의 모든 엔트리에 대한 키를 지정할 수 있습니다.
type DayOfTheWeek = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
type ChoresMap = { [day in DayOfTheWeek]: string };
const chores: ChoresMap = { // ERROR! Property 'saturday' is missing in type '...'
"sunday": "do the dishes",
"monday": "walk the dog",
"tuesday": "water the plants",
"wednesday": "take out the trash",
"thursday": "clean your room",
"friday": "mow the lawn",
};
물론, 이것을 범용 타입으로 할 수도 있습니다.
type DayOfTheWeek = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
type DayOfTheWeekMap<T> = { [day in DayOfTheWeek]: T };
const chores: DayOfTheWeekMap<string> = {
"sunday": "do the dishes",
"monday": "walk the dog",
"tuesday": "water the plants",
"wednesday": "take out the trash",
"thursday": "clean your room",
"friday": "mow the lawn",
"saturday": "relax",
};
const workDays: DayOfTheWeekMap<boolean> = {
"sunday": false,
"monday": true,
"tuesday": true,
"wednesday": true,
"thursday": true,
"friday": true,
"saturday": false,
};
2018년 10월 10일 갱신:아래 @dracstaxi의 답변을 확인해 주세요.내장 타입이 등장했습니다.Record이 모든 것이 당신에게 도움이 됩니다.
1.2.199 업데이트:답변에서 미리 작성된 매핑인터페이스를 완전히 삭제했습니다.@substaxi의 대답은 그들을 전혀 무관하게 만든다.그래도 사용하려면 편집 내역을 확인하십시오.
빠른 업데이트: Typescript 2.1이 내장되어 있기 때문에Record<T, K>사전과 같은 역할을 합니다.
이 경우 다음과 같이 선언할 수 있습니다.
var stuff: Record<string, any> = {};
리터럴 타입을 조합하는 것으로, 잠재적인 키를 제한 또는 지정할 수도 있습니다.
var stuff: Record<'a'|'b'|'c', string|boolean> = {};
다음은 문서에서 레코드 유형을 사용하는 일반적인 예입니다.
// For every properties K of type T, transform it to U
function mapObject<K extends string, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>
const names = { foo: "hello", bar: "world", baz: "bye" };
const lengths = mapObject(names, s => s.length); // { foo: number, bar: number, baz: number }
의 TypeScript 2.1 매뉴얼Record<T, K>
이것을 사용하는 것의 유일한 단점은{[key: T]: K}"키" 대신 사용하는 키의 종류에 대한 유용한 정보를 인코딩할 수 있습니다. 예를 들어 개체에 프라임 키만 있는 경우 다음과 같이 힌트할 수 있습니다.{[prime: number]: yourType}.
여기 이 변환에 도움이 되도록 제가 쓴 정규식이 있습니다.이렇게 하면 라벨이 "키"인 경우에만 변환됩니다.다른 라벨을 변환하려면 첫 번째 캡처 그룹을 변경하기만 하면 됩니다.
검색:\{\s*\[(key)\s*(+\s*:\s*(\w+)\s*\]\s*:\s*([^\}]+?)\s*;?\s*\}
대체:Record<$2, $3>
알 수 없는 키에 이름을 전달하고 유형을 쓸 수 있습니다.
type StuffBody = {
[key: string]: string;
};
이제 유형 검사에서 사용할 수 있습니다.
let stuff: StuffBody = {};
단, FlowType의 경우 이름을 지정할 필요가 없습니다.
type StuffBody = {
[string]: string,
};
실제로 내장된 유틸리티 레코드가 있습니다.
const record: Record<string, string> = {};
record['a'] = 'b';
record[1] = 'c'; // leads to typescript error
record['d'] = 1; // leads to typescript error
@Ryan Cavanaugh의 답변은 완전히 괜찮고 여전히 유효하다.그러나 대부분의 플랫폼이 ES6를 지원한다고 주장할 수 있는 16년 가을부터는 데이터를 키에 연관지을 필요가 있을 때는 항상 Map을 사용하는 것이 좋습니다.
쓸 때let a: { [s: string]: string; }활자본이 컴파일된 후에는활자 데이터 같은 것은 없고 컴파일에만 사용된다는 것을 기억해야 합니다.{ [ s : string ] : string ; } { }면 됩니다.
그렇다고 해도, 다음과 같이 쓸 수 있습니다.
class TrickyKey {}
let dict: {[key:TrickyKey]: string} = {}
할 수 없다.target es6 하면 '이렇게 하다'가 error TS1023: An index signature parameter type must be 'string' or 'number'.
따라서 실질적으로 문자열이나 숫자를 잠재적 키로 제한하므로 유형 검사를 수행하는 의미가 별로 없습니다. 특히 js가 번호로 키에 액세스하려고 하면 문자열로 변환된다는 점에 유의하십시오.
따라서 키가 문자열인 경우에도 Map을 사용하는 것이 베스트 프랙티스라고 가정해도 무방합니다.따라서 다음과 같이 하겠습니다.
let staff: Map<string, string> = new Map();
인터페이스 정의
interface Settings {
lang: 'en' | 'da';
welcome: boolean;
}
키를 설정 인터페이스의 특정 키로 강제 적용
private setSettings(key: keyof Settings, value: any) {
// Update settings key
}
@shabunc의 답변을 바탕으로 키 또는 값 중 하나 또는 둘 다 강제할 수 있습니다.
type IdentifierKeys = 'my.valid.key.1' | 'my.valid.key.2';
type IdentifierValues = 'my.valid.value.1' | 'my.valid.value.2';
let stuff = new Map<IdentifierKeys, IdentifierValues>();
should, 음, 음, 다, 다, 다, 다, 다, 다, 다, should, should, should, should, should,enumtype★★★★★★ 。
interface AccountSelectParams {
...
}
const params = { ... };
const tmpParams: { [key in keyof AccountSelectParams]: any } | undefined = {};
for (const key of Object.keys(params)) {
const customKey = (key as keyof typeof params);
if (key in params && params[customKey] && !this.state[customKey]) {
tmpParams[customKey] = params[customKey];
}
}
이 컨셉에 대한 아이디어를 얻으시면 코멘트를 달아주세요.
type KeyOf<T> = keyof T;
class SomeClass<T, R> {
onlyTFieldsAllowed = new Map<KeyOf<T>, R>();
}
class A {
myField = 'myField';
}
const some = new SomeClass<A, any>();
some.onlyTFieldsAllowed.set('myField', 'WORKS');
some.onlyTFieldsAllowed.set('noneField', 'Not Allowed!');
언급URL : https://stackoverflow.com/questions/13315131/enforcing-the-type-of-the-indexed-members-of-a-typescript-object
'codememo' 카테고리의 다른 글
| 외국 열쇠가 몽고에 있다고? (0) | 2023.02.27 |
|---|---|
| mongodb가 strict JSON을 출력하도록 강제합니다. (0) | 2023.02.27 |
| 문서 사용.react에서 querySelector를 선택하십시오.대신 레퍼런스를 쓸까요? 어떻게요? (0) | 2023.02.27 |
| Python에서 숫자 목록을 jsonarray로 변환하는 방법 (0) | 2023.02.27 |
| 동일 발신기지 정책을 회피하는 방법 (0) | 2023.02.27 |