TypeScript - 映射类型



TypeScript 中的映射类型用于通过转换现有类型的属性来创建新的类型。映射意味着在进行一些更改后,从现有元素创建新元素。类似地,映射类型意味着在对现有类型进行更改后创建新类型。因此,您可以重用现有类型来创建新类型。

内置映射类型

内置映射类型允许您转换现有类型,而无需手动转换类型。

以下是 TypeScript 中可用的内置映射类型。

  • Partial<T>:它通过使现有类型的所有属性可选来创建新类型。

  • Required<T>:它通过使现有类型的所有属性必填来创建新类型。

  • Readonly<T>:在新的类型中使所有属性可选。

  • Record<K, T>:创建一个类型,其中包含一组类型为 T 的属性 K。对于映射相同类型的属性很有用。

  • Pick<T, K>:通过从 T 中选择一组属性 K 来创建新类型。

  • Omit<T, K>:通过从 T 中省略一组属性 K 来创建新类型。

  • Exclude<T, U>:它通过排除可分配给 U 的 T 中的所有属性来创建新类型。

  • Extract<T, U>:它通过提取可分配给 U 的 T 中的所有属性来创建新类型。

  • NonNullable<T>:通过从 T 中排除 null 和 undefined 来构造一个类型。

示例

让我们通过一些 TypeScript 程序示例来了解一些常用的内置映射类型。

示例:使用 Partial 类型

在下面的代码中,我们创建了包含 name 和 age 属性的 Person 类型。之后,我们使用 Partial 实用程序类型从 Person 类型创建了一个新类型。

PartialPerson 类型具有 Person 类的所有属性,但所有属性都是可选的。我们定义了 PartialPerson 类型的 partialPerson 对象,它仅包含 name 属性,因为所有属性都是可选的。

// Creating the Person type
type Person = {
    name: string;
    age: number;
};

// Using the Partial mapped type
type PartialPerson = Partial<Person>;

// Creating an object of type PartialPerson
const partialPerson: PartialPerson = {
    name: "John",
    //   Age is optional
};
// Output
console.log(partialPerson);

编译后,它将生成以下 JavaScript 代码。

// Creating an object of type PartialPerson
var partialPerson = {
    name: "John"
};
// Output
console.log(partialPerson);

输出

{ name: 'John' }

示例:使用 ReadOnly 类型

在下面的代码中,我们使用 Readonly 实用程序类型创建了一个新类型,该类型具有 Person 类型的所有只读属性。如果我们尝试更改 partialPerson 对象的任何属性,它将抛出错误,因为它只读。

// Creating the Person type
type Person = {
    name: string;
    age: number;
};

// Using the ReadOnly mapped type
type PartialPerson = Readonly<Person>;

// Creating an object of type PartialPerson
const partialPerson: PartialPerson = {
    name: "John",
    age: 30
};

// Trying to change the name property
// partialPerson.name = "Doe"; // Error: Cannot assign to 'name' because it is a read-only property.
// Output
console.log(partialPerson);

编译后,它将生成以下 JavaScript 代码。

// Creating an object of type PartialPerson
const partialPerson = {
    name: "John",
    age: 30
};
// Trying to change the name property
// partialPerson.name = "Doe"; // Error: Cannot assign to 'name' because it is a read-only property.
// Output
console.log(partialPerson);

输出

{ name: 'John', age: 30 }

示例:使用 Pick 类型

在下面的代码中,我们创建了 Animal 类型,它包含 3 个属性。

之后,我们使用 Pick 实用程序类型仅从 Animal 类型中选择 name 和 species 属性,并创建一个名为 'AnimalNameAndSpecies' 的新类型。

animalNameAndSpecies 对象是 AnimalNameAndSpecies 类型,它仅包含 name 和 species 属性。

// Creating the Animal type
type Animal = {
    name: string;
    species: string;
    age: number;
};
// Using the Pick utility type to create a new type
type AnimalNameAndSpecies = Pick<Animal, 'name' | 'species'>;
// Creating an object of the AnimalNameAndSpecies type
const animalNameAndSpecies: AnimalNameAndSpecies = {
    name: 'Milo',
    species: 'Dog'
};
console.log(animalNameAndSpecies);

编译后,它将生成以下 JavaScript 代码。

// Creating an object of the AnimalNameAndSpecies type
const animalNameAndSpecies = {
    name: 'Milo',
    species: 'Dog'
};
console.log(animalNameAndSpecies);

输出

{ name: 'Milo', species: 'Dog' }

创建自定义映射类型

实用程序函数的功能有限。因此,创建自定义映射类型以根据您自己的约定映射类型非常重要。

语法

您可以按照以下语法创建自定义映射类型。

type MyMappedType<T> = {
    [P in keyof T]: NewType;
};
  • 'T' 是我们需要从中创建新的自定义映射类型的现有类型。

  • 'P' 是类型的属性。

  • 'keyof' 运算符获取类型 'T' 的每个键。

  • NewType 是要分配给类型属性 'P' 的新类型。

示例:使所有属性都为布尔值

在下面的代码中,我们创建了 Booleanify 类型,它将类型作为泛型参数。在类型主体内部,我们使用 '[P in keyof T]' 代码遍历类型 'T' 的每个键,并为其分配一个布尔值,因为我们正在将所有属性的类型更改为布尔值。

boolPerson 对象的所有属性都是布尔类型。

// Defining the Person type
type Person = {
  name: string;
  age: number;
};

// Creating the custom mapped type
type Booleanify<T> = {
    // Making all properties of Person type to Boolean
  [P in keyof T]: boolean;
};

// Creating an object of Booleanify type
const boolPerson: Booleanify<Person> = {
  name: true,
  age: true,
};
console.log(boolPerson);

编译后,它将生成以下 JavaScript 代码

// Creating an object of Booleanify type
const boolPerson = {
    name: true,
    age: true,
};
console.log(boolPerson);

输出

以上示例代码将产生以下输出

{ name: true, age: true }

示例:使所有属性都可选

在此示例中,我们无需使用内置实用程序类型 Partial 即可使现有类型的所有属性都可选。

这里,Animal 类包含 name 和 legs 属性。在代码 [key in keyof Animal]?: Animal[key] 中,问号 (?) 使属性可选,并且 Animal[key] 有助于保持属性类型相同。

现在,在 customAnimal 对象中,所有属性都是可选的。

// Defining the Animal type
type Animal = {
    name: string;
    legs: number;
};

// Creating custom type and making all properties optional using mapping
type CustomAnimal = {
    [key in keyof Animal]?: Animal[key];
};

// Creating an object of type CustomAnimal
let customAnimal: CustomAnimal = {
    name: "Dog",
    legs: 4,
};

console.log(customAnimal);

编译后,它将生成以下 JavaScript 代码

// Creating an object of type CustomAnimal
let customAnimal = {
    name: "Dog",
    legs: 4,
};
console.log(customAnimal);

输出

以上示例代码的输出如下

{ name: 'Dog', legs: 4 }

您可以使用实用程序函数或创建自定义映射类型来重用现有类型以创建新类型。这些自定义映射类型提高了代码的可读性,并帮助开发人员使代码易于维护。

广告