ts 当一个属性为联合类型时,如何通过它的取值来控制其他属性的类型?

我想要通过 IMap 这接口来获得一个类型,类型中有两个属性type 和 props, props 属性的类型会随着 type 属性的取值发生改变,type 的类型为 IMap 接口中的所有属性名的联合类型,props 的类型就是 type 取值在 IMap 中同名属性对应的类型。

interface IMap {
    a: number,
    b: string,
    c: boolean
    //...
}

type Config = {
    type: 'a',
    props: IMap['a']
} | {
    type: 'b',
    props: IMap['b']
} | {
    type: 'c',
    props: IMap['c']
}
// ...

通过这种方式写联合类型的方式可以达到我想要的结果,但是 IMap 中的属性有特别多,做不到将所有的组合都罗列出来,有什么解决办法吗?

阅读 563
avatarAI BotBETA

你可以使用 TypeScript 中的 keyofany 关键字来实现这个需求。首先,keyof 可以获取一个接口或类型所有的属性名,然后你可以通过 any 关键字来设定 props 的类型。请看下面的代码:

interface IMap {
    a: number,
    b: string,
    c: boolean
    //...
}

type Config = {
    type: keyof IMap,
    props: IMap[keyof IMap]
}

在这段代码中,Configtype 属性可以是 IMap 的任何一个键,而 props 的类型则是 IMap 中与 type 属性值相对应的类型。例如,如果 type'a',那么 props 就必须是 number 类型。

但是请注意,这种方式要求你在使用 Config 类型时必须确保 type 属性的值在 IMap 的键中存在,否则 TypeScript 会报错。如果你不能保证这一点,那么你就需要使用一个更复杂的类型,例如一个交叉类型或者一个自定义的泛型。

1 个回答
interface IMap {
  a: number;
  b: string;
  c: boolean;
  // ... 扩展更多属性
}

// 用映射类型和条件类型
type Config = {
  [K in keyof IMap]: {
    type: K;
    props: IMap[K];
  }
}[keyof IMap];

// 例子:
const configA: Config = { type: 'a', props: 42 }; // 正确
const configB: Config = { type: 'b', props: "hello" }; // 正确
const configC: Config = { type: 'c', props: true }; // 正确
推荐问题
logo
Microsoft
子站问答
访问
宣传栏