Typescript 객체에 string-> string의 매핑을 저장하고 모든 키가 문자열에 매핑되도록하고 싶습니다. 예를 들면 다음과 같습니다.
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
는 모든 식별자가 될 수 있으며 인터페이스 / 유형의 구문을 제안하는 데 사용해야합니다.
비슷한 구문을 사용하여 객체에 공용체 유형의 모든 항목에 대한 키가 있도록 할 수 있습니다.
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,
};
10.10.2018 업데이트 :
아래의 @ dracstaxi의 답변을 확인하십시오 . 이제 Record
대부분을 지원 하는 내장 유형 이 있습니다.
1.2.2020 업데이트 :
답변에서 사전 작성된 매핑 인터페이스를 완전히 제거했습니다. @ dracstaxi의 대답은 완전히 관련이 없습니다. 그래도 계속 사용하려면 편집 기록을 확인하십시오.
답변
빠른 업데이트 : Typescript 2.1부터 Record<T, K>
사전처럼 작동 하는 내장 유형 이 있습니다.
문서의 예 :
// 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>
답변
@Ryan Cavanaugh의 대답은 완전히 괜찮으며 여전히 유효합니다. ES16이 대부분의 플랫폼에서 지원된다고 주장 할 수있을 때 16 년 가을부터 추가 할 가치가 있습니다. 일부 키와 데이터를 연결해야 할 때마다 Map을 사용하는 것이 좋습니다.
우리가 글을 쓸 때 우리 let a: { [s: string]: string; }
는 타입 스크립트가 컴파일 된 후에 타입 데이터와 같은 것이 없다는 것을 기억할 필요가 있습니다. 오직 컴파일에만 사용됩니다. 그리고 {[s : 문자열] : 문자열; }는 {}로 컴파일됩니다.
그것은 당신이 다음과 같은 것을 쓸지라도 :
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>();
정의 enum
대신 사용하여 작동해야 type
합니다.