TS知识点总结(一)

TS知识点总结

一、ts中可选类型没有相关属性的问题

在项目中,有时候会遇到后端下发可选属性如:

在使用该类型的实例时如:
当 arr可能为undefined时,不能参与比较

arr?.length > 0 // 会报错
if (arr?.length) // 不会报错

二、interface与type的区别

相同点

两者都可以进行扩展,只是语法不同
interface

interface Name { 
  name: string; 
}
interface User extends Name { 
  age: number; 
}

type

type Name = { 
  name: string; 
}
type User = Name & { age: number  };

interface extends type

type Name = { 
  name: string; 
}
interface User extends Name { 
  age: number; 
}

type extends interface

interface Name { 
  name: string; 
}
type User = Name & { 
  age: number; 
}

不同点

type 可以而 interface 不行

1.type可以定义类型的别名,联合元素,元组类型

// 基本类型别名
type Name = string

// 联合类型
interface Dog {
    wong();
}
interface Cat {
    miao();
}

type Pet = Dog | Cat

// 具体定义数组每个位置的类型
type PetList = [Dog, Pet]


2.type可以使用typeof获得的实例类型进行赋值

// 当你想获取一个变量的类型时,使用 typeof
let div = document.createElement('div');
type B = typeof div

3.特殊操作

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

interface 可以而 type 不行

1.interface 能够声明合并

interface User {
  name: string
  age: number
}

interface User {
  sex: string
}

/*
User 接口为 {
  name: string
  age: number
  sex: string 
}
*/

2.interface可以被实现(implements

interface SpecialClass {
    age: number;
}

class SP implements SpecialClass {
    age: number;
    constructor(age: number) {
        this.age = age;
    } 
}

三、TS的协变与逆变

维基百科的定义:

协变与逆变(covariance and contravariance)是在计算机科学中,描述具有父/子型别关系的多个型别通过型别构造器、构造出的多个复杂型别之间是否有父/子型别关系的用语。

就是说原本具有父子关系的类型,在经过类型构造器后产生的类型是否还保持原本的父子关系。若是,称作协变;若父子关系颠倒,则称作逆变

例子:

interface Animal {
  age: number
}

interface Dog extends Animal {
  bark(): void
}

协变

let animals: Animal[]
let dogs: Dog[]

animals = dogs

animals[0].age // ok

那么,对于 type MakeArray<T> = T[] 这个类型构造器来说,它就是 协变(Covariance) 的。

逆变

有这样两个函数类型:

let visitAnimal = (animal: Animal) => void;
let visitDog = (dog: Dog) => void;

若是这样的函数实现:

let visitAnimal = (animal: Animal) => {
  animal.age
}

let visitDog = (dog: Dog) => {
  dog.age
  dog.bark()
}

visitAnimal = visitDog,这里会发生错误。赋值后,visitAnimal 指向的是visitDog的函数实现,所以在传入Animal类型的参数后就会报错。

但是相反,若visitDog = visitAnimalvisitDog指向的是visitAnimal 的函数实现,在传入Dog类型的参数后,并不会调用Dog类型专有的属性或方法,因此不会报错。这里,父子关系就发生了翻转,因此我们称type MakeFunction<T> = (arg: T) => void这种类型构造器就是逆变的。

参考文章:
[1]: https://juejin.cn/post/6855517117778198542
[2]: https://juejin.cn/post/6905666894984904717

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值