网站搜索

typescript - 如何从另一个类型接口创建类型/接口?


我有一个值类型的接口:

interface ValuesTypes {
  foo: string;
  bar: number;
}

以及控制联合:

type Controls = 'selectFoo' | 'tbxBar';

并将控件映射到值名称:

const mapControlsToValues: Record<Controls, keyof ValuesTypes> = {
  selectFoo: 'foo',
  tbxBar: 'bar',
};

我如何使用上面描述的代码获取 ElementsTypes 接口?

interface ElementsTypes {
  selectFoo: string;
  tbxBar: number;
}

答案#1

你定义 mapControlsToValues 的方式实际上行不通,因为你将每个值定义为 keyof ValuesTypes,这意味着每个值实际上可以是 foo 或 bar,而不是你传入的类型。

所以,我的建议是你应该依靠 TypeScript 的推断来完成这项工作!为了做到这一点,你必须创建一个泛型函数并使用你传入的“字面量”类型。这样你仍然可以保持相同的类型安全性,并且能够为你的 mapControlsToValues 对象提供具体的类型。

1- 创建一个通用函数

function getControlValues<T extends Record<Controls, keyof ValuesTypes>>(arg: T){
  return arg;
}

2- 提取生成类型的类型

const mapControlsToValues = getControlValues({
  selectFoo: 'foo',
  tbxBar: 'bar',
})

type ControlValuesType = typeof mapControlsToValues;

3- 基于你的 ControlValuesType 创建一个新的对象类型

type ElementsTypes = {
  [Key in keyof ControlValuesType]: ValuesTypes[ControlValuesType[Key]];
};

就是这样,你已经定义了一个遵循 ElementsTypes 接口的类型。如果你真的需要它成为一个接口,你总是可以像这样扩展创建的类型:

interface MyInterface extends ElementsTypes {}

TS 游乐场