1. 类型断言as

// <img id="why"/>
// 1.类型断言 as
/* 类型断言as通过我们的类型断言把一个相对来说比较普遍的一个类型转成我们一个
比较具体一点的类型,
,换成具体的类型的话,
我们就可以调具体类型里面的某些特殊的属性,或者某些特殊的方法, */
const el = document.getElementById("why") as HTMLImageElement;
el.src = "url地址";
// 2.另外案例: Person是Student的父类
class Person {}
class Student extends Person {
studying() {}
}
function sayHello(p: Person) {
(p as Student).studying();
}
const stu = new Student();
sayHello(stu);
// 3.了解: as any/unknown
const message = "Hello World";
// const num: number = (message as unknown) as number
export {};
2.非空类型断言!

// message? -> undefined | string
//别人有可能传,也有可能不传,如果不穿,你函数里面让获取length,所以写的不严谨,编译通过不了
//如果我们确认在调用的时候是一定有参数的,编译也没办法通过
//希望编译通过的化,第一种办法用If来判断,而是非空断言,告诉它我们这个message一定有值。
function printMessageLength(message?: string) {
// if (message) {
// console.log(message.length)
// }
// vue3源码
console.log(message!.length);
}
printMessageLength("aaaa");
printMessageLength("hello world");
3.可选链的使用
非空类型断言帮我们逃过了TS对他的检查,但是本质上来说的话,这个代码他依然是不严谨的。可选链可以让我们这个代码更加严谨一些。

type Person = {
name: string
friend?: {
name: string
age?: number,
girlFriend?: {
name: string
}
}
}
const info: Person = {
name: "why",
friend: {
name: "kobe",
girlFriend: {
name: "lily"
}
}
}
// 另外一个文件中
console.log(info.name)
// console.log(info.friend!.name)
console.log(info.friend?.name)
console.log(info.friend?.age)
console.log(info.friend?.girlFriend?.name)
// if (info.friend) {
// console.log(info.friend.name)
// if (info.friend.age) {
// console.log(info.friend.age)
// }
// }
4.??和!!的作用

let test;
let result = test ?? 8;
console.log(result); //8
result = null ?? 8;
console.log(result); //8
result = "abc" ?? undefined;
console.log(result); //abc
result = 0 ?? undefined;
console.log(result); //0
result = NaN ?? undefined;
console.log(result); //NaN
const message = "Hello World";
// const flag = Boolean(message)
// console.log(flag)
const flag = !!message;
console.log(flag);
let message: string|null = "Hello World"
const content = message ?? "你好啊, 李银河"
// const content = message ? message: "你好啊, 李银河"
console.log(content)
5.字面量类型

// "Hello World"也是可以作为类型的, 叫做字面量类型
//字面量类型的值和字面量类型必须保持一致
const message: "Hello World" = "Hello World";
// let num: 123 = 123
// num = 321
// 字面量类型的意义, 就是必须结合联合类型
type Alignment = "left" | "right" | "center";
let align: Alignment = "left";
align = "right";
align = "center";
// align = 'hehehehe'
6.字面量推理

const info = {
name: "why",
age: 18,
};
// info.name = "kobe";
//把鼠标放到info上面会自己推导出info的类型
// const info: {
// name: string;
// age: number;
// }
type Method = "GET" | "POST";
function request(url: string, method: Method) {}
const options = {
url: "https://www.coderwhy.org/abc",
method: "POST",
};
request(options.url, options.method);
/* 这样写的options.method会报错,因为options有类型推导,
推导出method是string类型,
但是 request方法里面要求method是Method类型。
const options: {
url: string;
method: string;
} */
export {};
这个时候解决办法
方法1:
type Method = "GET" | "POST";
function request(url: string, method: Method) {
console.log(url);
console.log(method);
/*
https://www.coderwhy.org/abc
POST
*/
}
type Request = {
url: string;
method: Method;
};
const options: Request = {
url: "https://www.coderwhy.org/abc",
method: "POST",
};
request(options.url, options.method);
export {};
方法2
type Method = "GET" | "POST";
function request(url: string, method: Method) {
console.log(url);
console.log(method);
/*
https://www.coderwhy.org/abc
POST
*/
}
type Request = {
url: string;
method: Method;
};
const options = {
url: "https://www.coderwhy.org/abc",
method: "POST",
};
request(options.url, options.method as Method);
//使用类型断言,将比较宽泛的类型转成比较具体的类型、
//本来method推导出来的是string类型,然后转成Method类型
export {};
建议使用方法1
7.类型缩小

7.1 typeof

7.2 平等缩小

7.4 instanceof

7.5

// 1.typeof的类型缩小
type IDType = number | string
function printID(id: IDType) {
if (typeof id === 'string') {
console.log(id.toUpperCase())
} else {
console.log(id)
}
}
// 2.平等的类型缩小(=== == !== !=/switch)
type Direction = "left" | "right" | "top" | "bottom"
function printDirection(direction: Direction) {
// 1.if判断
// if (direction === 'left') {
// console.log(direction)
// } else if ()
// 2.switch判断
// switch (direction) {
// case 'left':
// console.log(direction)
// break;
// case ...
// }
}
// 3.instanceof
function printTime(time: string | Date) {
if (time instanceof Date) {
console.log(time.toUTCString())
} else {
console.log(time)
}
}
class Student {
studying() {}
}
class Teacher {
teaching() {}
}
function work(p: Student | Teacher) {
if (p instanceof Student) {
p.studying()
} else {
p.teaching()
}
}
const stu = new Student()
work(stu)
// 4. in
type Fish = {
swimming: () => void
}
type Dog = {
running: () => void
}
function walk(animal: Fish | Dog) {
if ('swimming' in animal) {
animal.swimming()
} else {
animal.running()
}
}
const fish: Fish = {
swimming() {
console.log("swimming")
}
}
walk(fish)
网友评论