一、类型断言
类型断言(Type Assertion)可以用来指定一个值的类型
语法
值 as 类型
将一个父类断言为更加具体的子类
interface ApiError extends Error {
code: number;
}
interface HttpError extends Error {
statusCode: number;
}
function isApiError(error: Error) {
if (typeof (error as ApiError).code === 'number') {
return true;
}
return false;
}
二、interface与type的区别
1.相同点
1.1都可以描述一个对象或函数
interface User {
name: string
age: number
}
type User {
name: string
age: number
}
1.2 都允许拓展
interface 和 type 都可以拓展,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 extends interface 。 虽然效果差不多,但是两者语法不同
interface Name {
name: string;
}
interface User extends Name {
age: number;
}
type Name = {
name: string;
}
type User = Name & { age: number };
type Name = {
name: string;
}
interface User extends Name {
age: number;
}
interface Name {
name: string;
}
type User = Name & {
age: number;
}
2.不同点
2.1 type可以而interface不行
type 可以声明基本类型别名,联合类型,元组等类型
/ 基本类型别名
type Name = string
// 联合类型
interface Dog {
wong();
}
interface Cat {
miao();
}
type Pet = Dog | Cat
// 具体定义数组每个位置的类型
type PetList = [Dog, Pet]
type 语句中还可以使用 typeof 获取实例的 类型进行赋值
// 当你想获取一个变量的类型时,使用 typeof
let div = document.createElement('div');
type B = typeof div
其他操作
type StringOrNumber = string | number;
type Text = string | { text: string };
type NameLookup = Dictionary<string, Person>;
type Callback<T> = (data: T) => void;
type Pair<T> = [T, T];
type Coordinates = Pair<number>;
type Tree<T> = T | { left: Tree<T>, right: Tree<T> };
2.2 interface可以而type不行
interface 能够声明合并
interface User {
name: string
age: number
}
interface User {
sex: string
}
/*
User 接口为 {
name: string
age: number
sex: string
}
*/
三、工具类型
1、Partial
Partial<T>
构造类型T, 并将它所有的属性设置为可选的,它的返回类型表示输入类型的所有子类型
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate };
}
2、Readonly
Readonly<T>
构造类型T, 并将它所有的属性设置为readonly,也就是说构造出的类型的属性不能被再次赋值。
interface Todo {
title: string;
}
const todo:Readonly<Todo> = {
title: 'Delete inactive users'
}
3、Record<K,T>
构造一个类型,其属性名的类型为k, 属性值的类型为T, 这个工具可用来讲某个类型的属性映射到另一个类型上
interface PageInfo {
title: string;
}
type Page = 'home' | 'about' | 'contact';
const x:Record<Page,PageInfo> = {
about: {title: 'about'},
contact: {title: 'contact'},
home:{title:'home'}
}
4、Pick<T,K>
从类型T中挑选部分属性K来构造类型
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview =Pick<Todo, 'title' | 'completed'>;
const todo: TodoPreview = {
title:' Clean room',
completed: false
}
5、Exclude<T,U>
从类型T中剔除所有可以赋值给U的属性,然后构造一个类型
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude<string | number | (() => void), Function>; // string | number
6、Extract<T,U>
从类型T中提取所有可以赋值给U的类型,然后构造一个类型
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract<string | number | (() => void), Function>; // () => void
7、NonNullable
从类型T中剔除null和undefined,然后构造一个类型
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
8、ReturnType
由函数类型T的返回值类型构造一个类型
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<(<T>() => T)>; // {}
type T3 = ReturnType<(<T extends U, U extends number[]>() => T)>; // number[]
type T4 = ReturnType<typeof f1>; // { a: number, b: string }
type T5 = ReturnType<any>; // any
type T6 = ReturnType<never>; // any
type T7 = ReturnType<string>; // Error
type T8 = ReturnType<Function>; // Error
9、InstanceType
由构造函数类型T的实例类型构造一个类型
class C {
x = 0;
y = 0;
}
type T0 = InstanceType<typeof C>; // C
type T1 = InstanceType<any>; // any
type T2 = InstanceType<never>; // any
type T3 = InstanceType<string>; // Error
type T4 = InstanceType<Function>; // Error
10、Required
构造一个类型,使类型T的所有属性为required
interface Props {
a?: numnber;
b?: string;
}
const obnj: Props = { a: 5};
const obj2: Required<Props> = { a :5};
11、 ThisType
这个工具不会返回一个转换后的类型,它作为上下文的this类型的一个标记,注意,若向使用此类型,必须启用--noTmplicitThis.
type ObjectDescriptor<D, M> = {
data?: D;
methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
}
function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
let data: object = desc.data || {};
let methods: object = desc.methods || {};
return { ...data, ...methods } as D & M;
}
let obj = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
}
}
});
obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);