1.type 和interface的区别
定义语法不同:type也可以用来定义接口的数据结构,跟interface的语法不同
type Props = {};
interface Props {}
类型范围不同:interface一般表示object,class,function类型。type可以复杂类型(例如联合类型等)如下:
type JSXElementConstructor<P> =
| ((props: P) => ReactElement | null)
| (new (props: P) => Component<P, any>);
// 当你想要获取一个变量的类型时,可以使用typeof
let div = document.createElement('div');
type B = typeof div;
重名规范不同:interface定义接口允许重名,type不允许。interface重复定义的接口(包括class)会自动聚合。
interface Props {
x: string;
}
interface Props {
y: number;
}
// 两者会自动聚合为
interface Props {
x: string;
y: number;
}
继承语法不同:两者都可以继承,语法不同
interface IPoint {
x: number;
}
type Point = {
x: number;
}
// 接口继承接口
interface Point2 extends IPoint {
y: number;
}
// 接口继承type
interface Point2 extends Point {
y: number;
}
//type继承接口
type Point2 = IPoint & {y: number;}
//type继承type
type Point2 = Point & {y: nummber}
2.高级类型
高级类型:
交叉类型: a&b
联合类型: string | number
索引类型:k extends keyof t
映射类型: in keyof
Partial 把所有的属性变成可选的
定义:
type Partial<T> = {
[P in keyof T]?: T[P]
}
用法:
Required 所有的属性变成必填
定义:
type Required<T> = {
[P in keyof T]-?:T[P]
}
用法:
Readonly 所有的属性变成只读不可更改
定义:
type Readonly<T> = {
readonly [P in keyof T]: T[P]
}
用法:
Pick 从T中取出K中有的属性
定义:
type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}
用法:
Record 把k中的属性转成T类型
定义:
type Record<K extends keyof any, T> = {
[P in K]: T
}
用法:
Exclude, Extract
定义:
// 提取T中不包含在U中的属性
// 如果T能赋值给U,返回never类型,最终会将T中属于U的属性移除
type Exclude<T, U> = T extends U ? never : T;
// 提取T中包含在U中的属性
type Extract<T, U> = T extends U ? T : never;
Omit 忽略T中存在在K中的属性
定义:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
3.typeScript是什么
typeScript是微软开发的一款开源的编程语言,它是JavaScript的一个超集,本质上是为JavaScript增加了静态类型声明。
TypeScript相比于JavaScript具有以下优点:
- 更好的可维护性和可读性
- 引入了静态烈性声明,不需要太多的注释和文档,大部分的函数看类型定义就知道如何使用了
- 在解释阶段就能发现大部分因为变量类型导致的错误
4.typeScript的类型
- number:任意数字,let a:number
- string:任意字符串,let a:string
- boolean:布尔值true/false,let a:boolean
- 字面量:值本身,限制变量的值就是该字面量的值,let a:10,类似const,值只能是10
- any:任意类型,会导致其他的变量也不会检测
- unknown:任意类型,不会导致其他变量的检测,可以使用断言将unknown类型的值赋值给其他已知类型的变量
- void:空值(undefined)用于函数的返回值
- never:没有值,不能是任何值,一般用户错误处理函数的返回值类型定义
- object:任意的JS对象
- array:任意JS数组,let a:Array; let b: string[];
- tuple(元组):已知元素数量和类型的固定长度的数组
- enum(枚举)
枚举
使用枚举可以定义一些有名字的数字常量,枚举类型会被编译成一个双向映射的对象。枚举成员会被赋值为从0开始递增的数字,同时,也会被枚举值到枚举名进行反向映射。
使用枚举可以解决的问题:
- 可读性差:很难记住数字的含义
- 可维护差:硬编码,牵一发动全身
注意事项:
- 字符串枚举是不可以做双向映射的
- 异构枚举,把数字和字符串枚举混用,不推荐使用,会造成混乱
- 枚举成员的值不可修改
常量枚举:const enum
常量枚举回在编译阶段被移除
当我们不需要一个对象,而需要对象的值,就可以使用常量枚举,这样就可以避免在编译时生成多余的代码和简介引用
- 没有设置初始值
- 对已有枚举成员的引用
- 常量的表达式
需要计算的枚举成员:
这些枚举成员的值不会在编译阶段计算,而是保留到程序的执行阶段
enum Char {
a,
b= 1+2,
d = Math.random()
}
"use strict";
var Direction;
(function (Direction) {
Direction[Direction["Up"] = 1] = "Up";
Direction[Direction["Down"] = 2] = "Down";
Direction[Direction["Left"] = 3] = "Left";
Direction[Direction["Right"] = 4] = "Right";
})(Direction || (Direction = {}));
5.运算符
1. extends 泛型约束
2. keyof 返回接口的所有key的联合类型
3. extends ? xxx:sss. 条件判断
4. is 运算符 限定返回类型
5. in 运算符 会for循环出联合类型