这个问题是这个奇妙答案的后续:
https://stackoverflow.com/a/64753409/1068446
我想知道的是
为什么?
映射类型中的索引是否有效?
举个例子:
type MyData = {
a: {
alpha: string;
};
b: {
beta: number;
}
}
type NotNarrowPayload<T extends MyData> = {
key: keyof T;
fn: (data: T[keyof T]) => void;
}
type NarrowDataPayload<T extends MyData> = {
[K in keyof T]: {
key: K;
fn: (data: T[K]) => void;
}
}[keyof T];
function acceptsMTVTFunction<T extends MyData>(baseData: T,fn: NotNarrowPayload<T>) {
}
function acceptsMTVTFunction2<T extends MyData>(baseData: T,fn: NarrowDataPayload<T>) {
}
acceptsMTVTFunction(
{
a: {
alpha: "a"
},
b: {
beta: 99
},
},
{
key: "a",
fn: (data) => {
// TypeScript doesn't match the key to the value type, and this makes sense.
// (parameter) data: {
// alpha: string;
// } | {
// beta: number;
// }
}
}
);
acceptsMTVTFunction2(
{
a: {
alpha: "a"
},
b: {
beta: 99
},
},
{
key: "a",
fn: (data) => {
// (parameter) data: {
// alpha: string;
// }
}
}
);
TypeScript Playground
现在,说清楚一点——我理解第一种方法
不
工作
但我不明白为什么第二种方法
做
工作
如果我们仔细看一下:
type NarrowDataPayload<T extends MyData> = { // We're declaring an object
[K in keyof T]: { // For each key in T, it will have a property
key: K; // And these values will depend on T and K
fn: (data: T[K]) => void;
}
}[keyof T]; // But only keep the types accessible by keyof T.
问题是,TypeScript怎么知道我们在这里使用的键类型是“a”而不是“b”。