交叉类型(&)
将多个类型合并成一个类型
如下Test&Test1
合并成类型包含name
和age
所以如果只返回age
interface Test{
name: String;
}
interface Test1{
age: String;
}
function Test2(): Test & Test1{
return {
age:"12"
}
// ERROR Type '{ age: string; }' is not assignable to type 'Test & Test1'.
// Type '{ age: string; }' is not assignable to type 'Test'.
// Property 'name' is missing in type '{ age: string; }'.
// 新的类型少返回name了
}
联合类型(|)
声明的类型并不确定,可以为多个类型中的一个
interface Test{
name: String;
}
interface Test1{
age: String;
}
function Test2(): Test | Test1{
return {
age:"12"
}
}
// 因为是不确定的那么,所以只返回一个age也是可以的,说明该类型是Test
类型别名(type)
通过组合(交叉,联合,
keyof
等等操作符)作为一个新的类型并设置一个别名,这样,不需要每次都是用操作符操作一遍,万一需要改动,只需要改动type
的新类型即可
可以看到用新的P类型更完美,如果要改动,只需要改P类型即可,而不用单独再去一个一个改keyof Person
interface Person {
name: string;
age: number;
gender: string;
}
type P = keyof Person; //
// BAD
function IPersion():keyof Person{
return "name"
}
// BAD
function IPersion():keyof Person{
return "age"
}
// GOOD
function IPersion():P{
return "name"
}
keyof
获取类型的所有
key
的联合类型
interface Person {
name: string;
age: number;
gender: string;
}
type P = keyof Person; //
// 我们可以看到,keyof将Person这个对象类型映射成了一个联合类型
等于
type p = "name" | "age" | "gender"
Record<Keys, Type>
接收两个泛型参数,一个
keys
,一个Type
。keys
就是这个对象的key
,type
就是这个key
对应的类型。可以类比于a:string a
属性就是key
,type
就是string
。不过这里的type
可能更复杂
interface Person{
name: string;
age: number;
}
type User="user1"|"user2"
const Users: Record<User, Person> = {
user1: {
age: 1,
name:"123"
},
user2: {
age: 1,
name:"123"
}
}
// 可以看到keys 就是User中的user1和user2. 而Record中的第一个泛型参数就是作为键,而第二个参数Person作为值
// 所以就是新的类型就是以keys作为键,以type作为值
Partial
将一个类型转化为键?:对应类型的方式。即转换为各个属性非必填
Partial
类型定义:
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
可以看到Partial
就是将泛型T重新遍历出属性并加上?
符
interface Person{
name: string;
age: number;
}
// Person经过 Partial<Person>会转为
// interface Person{
// name?: string|undefined;
// age?: number|undefined;
// }
// ok
const Users1: Partial<Person> = {
name:"测试"
}
// ok
const Users2: Partial<Person> = {
}
// ok
const Users3: Partial<Person> = {
age:1
}
Required
和
Partial<Type>
相反,Required<Type>
会将属性变为必选的!
interface Person{
name?: string;
age: number;
}
const user1: Person = {
age:10
}
// Type '{ age: number; }' is not assignable to type 'Required<Person>'.
// Property 'name' is missing in type '{ age: number; }'.
// 这里可以看到报错了,Required<Type>将name转换为必选项了
const user2: Required<Person> = {
age: 10
}
Readonly
Readonly<Type>
同理一样是将Type转换为只读的属性
interface Todo {
title: string;
}
const todo: Readonly<Todo> = {
title: "Delete inactive users",
};
// Cannot assign to 'title' because it is a constant or a read-only property.
// 可以看到title属性成了只读,所以会报错
todo.title = "Hello";
Pick<Type, Keys>
从
Type(类型)
中取出keys
属性作为新的类型
interface Todo {
title: string;
description: string;
completed: boolean;
}
// 从Todo类型中取出title和completed组成新的类型。
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
};
Omit<Type, Keys>
和
Pick<Type, Keys>
相反,Pick<Type, Keys>
是从类型中取出属性作为新的类型,Omit<Type, Keys>
是从类型中忽略属性,之后剩下的属性组成新的类型
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
// TodoPreview 这个新类型没有description属性
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
createdAt: 1615544252770,
};
Exclude<UnionType, ExcludedMembers>
从联合类型中去除其中一个类型,而组成新的类型
type T0 = Exclude<"a" | "b" | "c", "a">;
// Type '"a"' is not assignable to type '"b" | "c"'.
// 这里就会报错,因为这里从联合类型中去掉了a, 那么新的T0类型其实是 type T0 = "b"|"c"
const t1:T0 = "a"
Extract<Type, Union>
和
Exclude<UnionType, ExcludedMembers>
相反,Extract<Type, Union>
从类型中提取Union
联合类型作为新的类型。
type T0 = Extract<"a" | "b" | "c", "a" | "f">;
// 转换为
type T0 = "a"