typescript 我怎样才能创建一个只接受来自另一个类型的属性列表的类型?

vawmfj5a  于 2022-12-19  发布在  TypeScript
关注(0)|答案(1)|浏览(125)

我正在尝试创建一个"FormField"泛型类型,它将采用另一种类型,并且只接受该类型的属性名称/值元组+一些属性,如"checked"。
示例:

const formProperties: FormField<User> = [{name: "name", value: "Toto", checked: false}, {name: "age", value: 30, checked: true}]` with User defined like this : `interface User { name: string; age: number;}` or even `const formProperties: FormField<House> = [{name: "width", value: 100, checked: true}, {name: "height", value: 50, checked: false}]` with House : `interface House { width: number; height: number; }

我知道我可以用

{name: string; value: string | number | CustomType }[]

但是我不知道"值"的类型。
我也尝试了一些Map类型的方法,但也没有成功。

type FormField<T> = {[Property in keyof T]: T[Property]};
hfyxw5xn

hfyxw5xn1#

溶液

type FormFieldItem<T, Key extends keyof T> = {
  name: Key;
  value: T[Key];
  checked: boolean;
}

type FormField<T> = {
  [K in keyof T]: FormFieldItem<T, K>;
}[keyof T][];

这里发生了什么?

为了简单起见,我将单个列表项提取到它自己的类型FormFieldItem中,这也使得将来扩展它变得更容易。
FormFieldItem采用两个通用参数:

  • T:用于Map指定Key类型的整个对象
  • Key:Mapkey属性的类型和value属性的类型

我们可以在FormField类型中使用FormFieldItem类型来首先构造一个新对象,在该对象中我们将对象(T)的每个键Map到相应的FormFieldItem。然后我们可以将所有keyof TMap到所创建的对象上,以获得所有可能的FormFieldItem的并集。最后我们期望这些并集的列表(最后的[])。

有用吗?

您可以使用描述中提供的值对此进行测试。Interactive TypeScript Playground链接

interface User { name: string; age: number; }

const formProperties: FormField<User> = [
  // valid
  { name: "name", value: "Toto", checked: false },
  // valid
  { name: "age", value: 30, checked: true },
  // invalid
  { name: "name", value: 30, checked: true },
];

相关问题