在 TypeScript 中创建一个可选属性 Required

目录

Make an optional property Required in TypeScript

  1. 在 TypeScript 中设置可选属性为必需
  2. 制作 TypeScript 所需的所有属性

在 TypeScript 中创建一个可选属性 Required

要使可选属性成为必需属性,请创建一个实用程序类型,该实用程序类型使用映射修饰符来删除指定属性的可选性。

新类型将具有标记为必需的指定属性。

索引.ts
interface Employee { id?: number; name: string; salary?: number; } type WithRequiredProperty<Type, Key extends keyof Type> = Type & { [Property in Key]-?: Type[Property]; }; // 👇️ Make salary required const emp1: WithRequiredProperty<Employee, 'salary'> = { name: 'Bobby Hadz', salary: 100, };

我们创建了一个
实用程序类型
,它接受一个类型和一个属性名称,并使该属性成为必需的。

您可以使用实用程序类型来创建多个属性,方法是用竖线分隔它们的名称。

索引.ts
interface Employee { id?: number; name: string; salary?: number; } type WithRequiredProperty<Type, Key extends keyof Type> = Type & { [Property in Key]-?: Type[Property]; }; // 👇️ Make salary and id required const emp1: WithRequiredProperty<Employee, 'salary' | 'id'> = { id: 0, name: 'Bobby Hadz', salary: 100, };

-?:语法称为
映射修饰符
,用于影响可选性。

它用于内置的
Required实用程序类型,如下
所示

索引.ts
/** * Make all properties in T required */ type Required<T> = { [P in keyof T]-?: T[P]; };

在我们的例子中,我们只需要一个属性。

索引.ts
interface Employee { id?: number; name: string; salary?: number; } type WithRequiredProperty<Type, Key extends keyof Type> = Type & { [Property in Key]-?: Type[Property]; }; const emp1: WithRequiredProperty<Employee, 'salary'> = { name: 'Bobby Hadz', salary: 100, };

另一种可能更易于阅读的解决方案是扩展
类型别名

接口
并覆盖要设置为必需的属性。

扩展类型别名或接口

或者,您可以扩展接口或类型别名,创建一个新接口,您可以在其中将可选属性设置为必需的。

索引.ts
interface Employee { id?: number; name: string; salary?: number; } interface EmployeeWithSalary extends Employee { salary: number; // 👈️ is now required id: number; // 👈️ is now required } const emp2: EmployeeWithSalary = { id: 1, name: 'Bobby Hadz', salary: 200, };

EmployeeWithSalary接口扩展Employee并覆盖salary
id属性,将它们设置为必需的。

如果省略任何必需的属性,我们将收到类型检查错误。

索引.ts
interface Employee { id?: number; name: string; salary?: number; } interface EmployeeWithSalary extends Employee { salary: number; // 👈️ is now required id: number; // 👈️ is now required } // ⛔️ Error: Property 'id' is missing in type // '{ name: string; salary: number; }' but // required in type 'EmployeeWithSalary'.ts(2741) const emp2: EmployeeWithSalary = { name: 'Bobby Hadz', salary: 200, };

制作 TypeScript 所需的所有属性

使用Required实用程序类型使类型中的所有属性成为必需的。

索引.ts
interface Employee { id?: number; name?: string; salary?: number; } const emp: Required<Employee> = { id: 1, name: 'Bobby Hadz', salary: 1000, };

实用Required程序类型构造一个新类型,其中提供的类型的所有属性都设置为必需。

索引.ts
interface Employee { id?: number; name?: string; salary?: number; } // 👇️ type T = { // id: number; // name: string; // salary: number; // } type T = Required<Employee>;

Required您可以在 TypeScript 的
Github 存储库中看到内置类型是如何实现的

索引.ts
/** * Make all properties in T required */ type Required<T> = { [P in keyof T]-?: T[P]; };

-?:语法称为
映射修饰符
,用于影响可选性。

当以减号为前缀时,映射修饰符会删除类型属性的可选性。

实用程序类型基本上采用所提供类型的所有属性并删除它们的可选性(使它们成为必需的)。

?:映射修饰符可以通过两种方式影响可选性,例如,您还可以使用它们通过在 前面加上加号 ( +?:)来使一个类型的所有属性成为可选的。

如果您不添加前缀,则+假定为。

索引.ts
/** * Make all properties in T optional */ type Partial<T> = { [P in keyof T]?: T[P]; };

这是
实用程序类型

代码Partial,它使类型中的所有属性都是可选的。

请注意,这两种类型之间的唯一区别是类型中问号前面的减号Required

-?:语法删除了可选性,而?:(or +?:) 使类型中的所有属性都是可选的。