Typescipt 干货解读
首先申明,以下文章都是我本人粗俗的了解,不喜爱请留下意见,哪里写的不对也请挑出,互相学习改过
类型注解 & 类型推断
类型注解
例:
let count: number;
count = 123;
意思是显示的通知代码,咱们的 count
变量就是一个数字类型,这就叫做 类型注解
这之后你再把 count 改成字符串就会报错
要留神的是只管有谬误,js 文件还是被编译创立了。就算你的代码里有谬误,你依然能够应用 TypeScript。但在这种状况下,TypeScript 会正告你代码可能不会按预期执行。
类型推断
let countInference = 123;
这时候我并没有显示的通知你变量 countInference
是一个数字类型,然而如果你把鼠标放到变量上时,你会发现 TypeScript 主动把变量正文为了number
(数字)类型,也就是说它是有某种推断能力的,通过你的代码 TS 会主动的去尝试剖析变量的类型。
点这里演示代码
函数参数和返回值
// 函数参数和返回值
function getTotal(one: number, two: number): number {return one + two;}
// 函数无返回值时,类型是 void
function sayHi(): void {console.log('我说嘿,你说 --')
}
// 函数传参是对象
function add ({one, two}: {one: number, two: number}): number {return one + two + ''}
function getNumber({one}: {one: number}) {return one}
function anything (one) {return one} // 不注解默认是 any
点击这里演示代码
对 TS 反对好的 IDE
webstorm2020.2 以上 vscode 都对 TS 有很好的提醒成果
数组类型
let numberArr = [1, 2, 3]
numberArr = [1, '']
const numberArr1: number[] = [1, 2, 3]
const undefinedArr : undefined[] = [undefined, undefined]
const arr: (string | number)[] = [1, 2, ' ']
// 对象数组
const chengxuyuan: {name: string, age: number}[] = [
{
name: 'yueshuang',
age: 16
},
{
name: 'chongwei',
age: 20
}
]
// 类型别名
type Chengxuyuan = {
name: string
age: number
}
// 重写
const chengxuyuan2: Chengxuyuan[] = [
{
name: 'yueshuang',
age: 16
},
{
name: 'chongwei',
age: 20
}
点我演示
元组的呈现
元组类型容许示意一个 * 已知元素数量和类型 * 的数组,各元素的类型不用雷同
let x: [string, number] = ['', 2]
// 应用场景:个别用于 csv 这种列举,别的?const chengxuyuan: [string, string, number][] = [["xiaohong", "xiaobai", 18],
["jiwenge", "jiagoushi", 28],
["cuihua", "teacher", 25],
];
接口 interface
-
与类型别名的区别
- type date = string | number 类型别名能够是这种模式,也能够是 type g = string | number[]接口必须是:
- 什么时候应用类型别名?答:无奈用接口来形容一个类型,且须要应用联结类型或元组时
- 尽量应用接口
- 类型别名不能被 extends 和 implements
interface StringObj {
name: string
other: string
}
- 能不能写任何对象的属性都不被束缚?
const obj: {
name: string,
age: number,
[prototype: string]: any
} = {
name: '',
age: 18,
other1: '',
other2: 8
}
- 也能够对办法进行束缚
interface Chenxuyuan {
name: string
age: number
say(): string // 办法的返回值需是 string}
类的概念
重写
好玩的例子:
class Chengxuyuan {
content = '好的, 这个需要马上做'
say() {return this.content}
}
let xiaojing = new Chengxuyuan() // 晓静连忙反馈
console.log(xiaojing.say())
// 继承
class Lihaidechengxuyuan extends Chengxuyuan {saySomething() {return '然而,这个需要要排期...'}
}
let chongwei = new Lihaidechengxuyuan() // 崇伟十分的理智
console.log(chongwei.say())
console.log(chongwei.saySomething())
// 重写
class NPchengxuyuan extends Chengxuyuan {say() {return '这个需要做不了!'}
saySomething() {return super.say() // 子类调用父类办法
}
}
let brotherBo = new NPchengxuyuan() // 当产品遇见波哥
console.log(brotherBo.say())
console.log(brotherBo.saySomething(
点我演示
类的拜访类型 public private protected
类的外部和内部
public
意思就是容许在类的外部和内部被调用
// 轻易写一个类
class Person {name: string = ''}
const person = new Person()
person.name = '我是打工人'
console.log(person.name) // 我是打工人
这时候能够打出我是打工人是因为咱们如果不在类里对 name
的拜访属性拜访类型进行定义,那么它就会默认是 public
拜访属性。
相当于:
class Person {public name:string;}
private
// private
class Person2 {
private name:string;
public sayHello(){console.log(this.name + 'say Hello') // 此处不报错
}
}
//------- 以下属于类的内部 --------
const person2 = new Person2()
person2.name = 'haha' // 此处报错
person2.sayHello()
console.log(person2.name) // 此处报错
protected
// protected
class Person3 {
protected name: string
public sayHello() {console.log(this.name + 'say Hello') // 此处不报错
}
}
class Chengxuyuan extends Person3 {say() {return this.name // 在继承中能够被应用}
}
//------- 以下属于类的内部 --------
const person3 = new Chengxuyuan()
person3.name = 'haha' // 此处报错,在内部还是不行
person3.sayHello()
console.log(person3.name) // 此处报错,在内部还是不行
总结:
- 如果是 private,只有是在类内部应用就会报错
- 如果是 Protected,在类内部调用也会报错,然而,protected 的属性能够在继承中被应用,但子类中在内部应用还是不行
类的构造函数
// 简洁写法
class Person{constructor(public name:string){}}
// 继承
class Codeman{constructor(public name:string){}}
class Teacher extends Codeman{constructor(public age:number){super('hahaha')
}
}
const teacher = new Teacher(18)
console.log(teacher.age) // 18
console.log(teacher.name) // hahah
点我演示
规定:
- 在子类里写构造函数时,必须用
super()
调用父类的构造函数,如果须要传值,也必须进行传值操作 - 就算是父类没有构造函数,子类也要应用
super()
进行调用,否则就会报错 - 父类 constructor 中参数有几个,子类 super 中就应该传几个,否则也会报错
类的 getter setter 和 static
// 从网红直播看 getter
class Xiaojiejie {constructor(private _age: number){} // 小姐姐的实在年龄,不能够轻易通知他人
get age() { // 你要是非要问呢,那就报给你一个假年龄
return this._age - 3
}
}
let wanghong = new Xiaojiejie(35) // 假如这个网红 35 岁了
console.log(wanghong.age) // 失去网红的年龄是 32
// 从小朋友想去 KTV 看 setter
class KTVPlayer {constructor(private _age:number){}
get age(){return this._age}
set age(age:number){this._age = age + 5}
}
let xiaojie = new KTVPlayer(15) // 小洁未满 18 岁,不让去 KTV 玩
xiaojie.age = 18 // kTV 给小洁伪造年龄
console.log(xiaojie.age) // 当初小洁 23 岁
点我演示
static 不想 new 对象,间接用
class Girl {static sayType() {return "我是慢热型";}
}
Girl.sayType = () => {return '你是高冷型'}
console.log(Girl.sayType()); // 你认为你慢热,然而我认为你就是高冷
抽象类和只读属性
只读属性
class Person {
public readonly _content: string = ''
constructor(content: string) {this._content = content}
}
let shenteng = new Person('我年老时候可是校草')
console.log(shenteng._content) // 我年老时候可是校草
shenteng._content = '你太胖了,基本不是校草' // 报错,不许改,气死你
abstract 抽象类 形象办法(此处 cue 晓静)
- 形象办法必须在抽象类中能力应用
- 个别抽象类不被间接实例化应用,而是被用于 一个 束缚子类必须给我实现 的形式
- 形象方只定义名字和类型,是不在外面写具体实现的。
- 形象 办法 必须在子 类中实现,否则子类会报错
abstract class FrontEnd {abstract skill(): string // 前端工程师必须在简历里填写技能
}
class Basic extends FrontEnd {skill() {return '我是高级小白'}
}
点我演示
联结类型和类型爱护(类型守护)as in typeof instanceof
用 as 进行类型断言
类型断言有两种,as 和 <> 模式,然而因为尖括号对 jsx 不敌对,所以个别尽量用 as
interface Basic {
highT: boolean;
code: () => {}
}
interface High {
highT: boolean;
ppt: () => {};
}
function judgeWho(animal: Basic | High) {if (animal.highT) {(animal as High).ppt(); // 高 T 做 PPT}else{(animal as Basic).code(); // 一般小白写代码}
用 in
function judgeWhoTwo(animal: Basic | High) {if ("ppt" in animal) {animal.ppt();
} else {animal.code();
}
}
typeof
// typeof
function add(first: string | number, second: string | number) {if (typeof first === "string" || typeof second === "string") {return `${first}${second}`;
}
return first + second;
}
枚举类型
反向查问只能是数字的时候才能够
enum constant {
'one' = 1,
'two',
'three'
}
// console.log(constant[3])
enum g {
xixi,
haha
}
// console.log(g['xixi']) // []内必须是字符串
enum test {
name = '名称',
age = '年龄',
show = '秀'
}
console.log(test['名称']) /
装璜器
链接
其余
- Omit 用来剔除 复用的类型中的某些属性
interface User {
id: number
role: string
name: string
token: string
}
type UserWithoutTOken = Omit<User, 'token'>
let obj: UserWithoutTOken = {
id: 2,
role: 'string',
name: 'string'
- 泛型在 jsx 中会被当做标签,用 extends 化解
const toArray = <T extends {}>() => {}
- keyof 的用法
// 索引查问
interface Rectangle {
x: number;
y: number;
width: number;
height: number;
}
type keys = keyof Rectangle;
// 这里应用了泛型,强制要求第二个参数的参数名必须蕴含在第一个参数的所有字符串索引中
function getRectProperty<T extends object, K extends keyof T>(rect: T, property: K): T[K] {return rect[property];
}
// 传入两个参数 rect 和 property 返回 rect 的属性值 rect[property]
// rect 的类型假设为 T property 的类型假设为 K 那么返回的类型则是 T[K]
// 设置泛型的时候 定义 T 是 object 类型的 T extends object
// 设置 K 是 T 的属性 K extends keyof T
let rect: Rectangle = {
x: 50,
y: 50,
width: 100,
height: 200
};
console.log(getRectProperty(rect, 'width')
- Partial 类型
// Partial 类型,定义不用填属性
// 该类型已内置在 TypeScript 中
// type Partial<T> = {// [P in keyof T]?: T[P]
// };
interface Rectangle {
x: number;
y: number;
width: number;
height: number;
}
type PartialRectangle = Partial<Rectangle>;
// 等价于
// type PartialRectangle = {
// x?: number;
// y?: number;
// width?: number;
// height?: number;
// }
// let rect: PartialRectangle = {
// width: 100,
// height: 200
// };
let rect: PartialRectangle = {
width: 100,
height: 200
- Pick 类型 – 捡出须要的属性
// // 该类型已内置在 TypeScript 中
// type Pick<T, K extends keyof T> = {// [P in K]: T[P]
// };
interface User {
id: number;
name: string;
age: number;
gender: number;
email: string;
}
type PickUser = Pick<User, "id" | "name" | "gender">;
// 等价于
// type PickUser = {
// id: number;
// name: string;
// gender: number;
// };
let user: PickUser = {
id: 1,
name: 'tom',
gender: 1,
- Exclude – 剔除不须要的属性, 跟 Omit 有点像
// 该类型已内置在 TypeScript 中
// 这里应用了条件类型(Conditional Type),和 JS 中的三目运算符成果统一
// type Exclude<T, U> = T extends U ? never : T;
interface User {
id: number;
name: string;
age: number;
gender: number;
email: string;
}
type keys = keyof User; // -> "id" | "name" | "age" | "gender" | "email"
type ExcludeUser = Exclude<keys, "age" | "email">;
// 等价于
// type ExcludeUser = "id" | "name" | "gender
tsconfig.json
- include exclude
- removeComments 编译后去掉正文
- noImplicitAny: true 不必非设置 any
- node 是遵循 tsconfig.json 的配置的,即,若 include 中没有某文件,node 去执行编译的时候也是不会编译的
- rootDir outDIr 源文件 -> 编译后文件的地址
- noUnusedLocals noUnusedParameters 不必的变量和参数 回收删除
- 配置解释地址