Я пытаюсь создать карту из набора строковых ключей для набора специфицированных c строк:
type Datum = { LOCATION: string, GENDER: number }
export const fieldKeys: Record<strings, keyof Datum> = {
country: "LOCATION",
gender: "GENDER"
};
, чтобы позже я мог индексировать объект типа Datum
через один из ключей поля:
const d: Datum = { /* … */ }
const country = d[fieldKeys.country]
Однако, поскольку ключи записи fieldKeys
являются произвольными строками, а не общеизвестным набором свойств, допускается неправильное использование:
// Passes type checker but is a bug.
const bug = d[fieldKeys.doesNotExist]
Кроме того, предполагаемый тип свойства при доступе через fieldKeys является типом объединения всех возможных значений свойства Datum:
// Inferred type is 'string | number' instead of string.
const shouldBeString = d[fieldKeys.country]
В идеале TypeScript должен определять ключи записи, но код, подобный этому, не является разрешено, поскольку это рекурсивно:
export const fieldKeys: Record<keyof (typeof fieldKeys), keyof Datum> = {
country: "LOCATION",
gender: "GENDER"
};
Я могу обойти это с помощью стандартного кода, как это, но это не очень хорошее решение:
const keyOf = <D, K extends keyof D>(k: K): K => k
export const fieldKeys = {
country: keyOf<Datum, "LOCATION">("LOCATION"),
gender: keyOf<Datum, "GENDER">("GENDER")
} as const;
В целом, я хотел бы следующие, чтобы пройти проверку типа:
type Datum = { LOCATION: string, GENDER: number }
export const fieldKeys = {
country: "LOCATION",
gender: "GENDER",
// Requirement: Type checker complains that NODATUMPROPERTY is is not a property of Datum.
noDatumProperty: "NODATUMPROPERTY"
};
const d: Datum = { LOCATION: "Germany", GENDER: 1 }
// Requirement: inferred type is 'string'
const country = d[fieldKeys.country]
// Requirement: Type checker complains about non-existing property in fieldKeys.
const bug1 = d[fieldKeys.doesNotExist]
У кого-нибудь есть идеи, как это сделать?