如果你预先知道Mapping 结构,你就可以做到。
首先您需要使用mapped types 来创建所有可能/允许的数据结构:
interface Mapping {
"x": (a: string) => void
"y": (b: number) => void
}
type Variants<Dictionary> = {
[Prop in keyof Dictionary]: {
name: Prop,
fn: Dictionary[Prop]
}
}
// type Result = {
// x: {
// name: "x";
// fn: (a: string) => void;
// };
// y: {
// name: "y";
// fn: (b: number) => void;
// };
// }
type Result = Variants<Mapping>
您可能已经注意到,我们最终得到了嵌套对象,其中值表示允许的状态。现在,我们需要以某种方式获得允许值的联合,或者换句话说,创建一个discriminated union type
考虑一下:
type Values<T> = T[keyof T]
interface Mapping {
"x": (a: string) => void
"y": (b: number) => void
}
type Variants<Dictionary> = {
[Prop in keyof Dictionary]: {
name: Prop,
fn: Dictionary[Prop]
}
}
// type Result = {
// name: "x";
// fn: (a: string) => void;
// } | {
// name: "y";
// fn: (b: number) => void;
// }
type Result = Values<Variants<Mapping>>
我已将我们的结果包装在 Values 实用程序类型中。此类型返回没有键的所有对象值的联合。这实际上是我们想要的。
我们也可以稍微重构一下:
type Values<T> = T[keyof T]
interface Mapping {
"x": (a: string) => void
"y": (b: number) => void
}
type Variants<Dictionary> = Values<{
[Prop in keyof Dictionary]: {
name: Prop,
fn: Dictionary[Prop]
}
}>
type Handlers = Variants<Mapping>
const x: Handlers = {
name: "x",
fn(prop /* :string */) { }
}
const y: Handlers = {
name: "y",
fn(prop /* :number */) { }
}
Playground
您不需要使用任何额外的通用参数。
Here你可以找到类似的问题,here你可以找到我的文章。