ts补充内容

544 阅读3分钟

一、类型断言

类型断言(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中剔除nullundefined,然后构造一个类型

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);