Zwężenie typu T [K] przy użyciu K wydłuża klucz T [duplikat]
Nov 21 2020
Próbuję zdefiniować interfejs, w którym:
- jedna właściwość jest kluczem typu ogólnego
- inna właściwość zależy od typu wartości skojarzonej z tym kluczem z innej właściwości
Najbliższe, jakie mogę uzyskać, to rozwiązanie T [K] przez Typescript do typów unii wszystkich wartości T. Wygląda jednak na to, że powinien istnieć sposób na dalsze zawężenie tego, jeśli K jest znanym literałem ciągu.
Oto przykład tego, co próbuję zrobić.
Test
interface Person {
age: number;
name: string;
}
interface ColumnDef<T, K extends keyof T> {
key: K;
renderData: (value: T[K]) => void;
}
interface Report<T> {
columns: ColumnDef<T, keyof T>[];
}
const report: Report<Person> = {
columns: [
{
key: "age", // this is correctly typed to be "age"|"name"
renderData: (value) => {
// ideally value should be "number" here, but it is "string|number"
}
},
{
key: "name", // this is correctly typed to be "age"|"name"
renderData: (value) => {
// ideally value should be "string" here, but it is "string|number"
}
},
]
}
Odpowiedzi
1 CraigC Nov 21 2020 at 03:20
Podążając za pokrewnym pytaniem związanym z kapitanem Yossarianem, byłem w stanie zawęzić typ za pomocą tej odpowiedzi .
Na wypadek, gdyby to komuś pomogło, oto jak zastosowałem to w moim przykładowym przypadku.
interface Person {
age: number;
name: string;
}
type ColumnDef<T> = {
[K in keyof T]-?: BaseColumnDef<T, K>
}[keyof T]
interface BaseColumnDef<T, K extends keyof T> {
key: K;
renderData: (value: T[K]) => void;
}
interface Report<T> {
columns: ColumnDef<T>[];
}
const report: Report<Person> = {
columns: [
{
key: "age", // this is correctly typed to be "age"|"name"
renderData: (value) => {
// value is now type "number"
}
},
{
key: "name", // this is correctly typed to be "age"|"name"
renderData: (value) => {
// value is now type "string"
}
},
]
}