TS
一、类型检测
0、type定义类型别名,方便多次复用
type IDType = string | number | boolean
type PointType = {
x: number
y: number
z?: number
}
function printId(id: IDType) {
}
function printPoint(point: PointType) {
}
1、number、string、boolean 类型
let name: string = "why";
let num1: number = 100;
let flag: boolean = true;
2、array类型
- array类型里只能放同一种类型,如:string[ ]代表数组里只能放string类型
const names1: Array<string> = [];
const names2: string[] = [];
3、tuple类型
- tuple类型里可以放多种类型,但类型需要一一对应
const info: [string, number, number] = ["why", 18, 1.88];
const name = info[0];
console.log(name.length);
const age = info[1];
console.log(age.length);
- 因为tuple里面可以放多个类型,所以比较适合作为函数的返回值
function useState(state: any): [any, (newState: any) => void] {
let currentState = state;
const changeState = (newState: any) => {
console.log(newState);
};
return [currentState, changeState];
}
4、object类型
const info: {
name: string;
age: number;
} = {
name: "why",
age: 18,
};
console.log(info.name);
5、null 和 undefined
let n1: null = null;
let n2: undefined = undefined;
let flag = true;
let result: unknown;
if (flag) {
result = 123;
} else {
result = "abc";
}
console.log(result);
6、Symbol类型
const title1 = Symbol("title");
const title2 = Symbol("title");
const info = {
[title1]: "程序员",
[title2]: "老师",
};
console.log(info[title1]);
7、void类型
函数无返回值的类型就是void
function sum(num1: number, num2: number) {
console.log(num1 + num2);
}
8、never类型
never类型不匹配任何类型,所以赋任何类型的值都会报错
function handleMessage(message: string | number | boolean) {
switch (typeof message) {
case "string":
console.log("string处理方式处理message");
break;
case "number":
console.log("number处理方式处理message");
break;
default:
const check: never = message;
}
}
handleMessage(true);
9、any类型
在不想给某些JavaScript添加具体的数据类型时,可以使用any类型,便会跳过类型检测,和原生的JavaScript代码是一样的;
let message: any = "Hello World";
message = 123;
message = true;
message = {};
10、字面量类型
字面量类型 ,值和类型是保持一致的,常结合联合类型使用
type Method = "GET" | "POST";
type Request = {
url: string;
method: Method;
};
function request(url: string, method: Method) {}
const options: Request = {
url: "https://www.coderwhy.org/abc",
method: "POST",
};
11、函数相关的类型
- 函数的参数和返回值都需要确定类型,参数必须明确写出类型,返回值默认会自动推导;
function sum(num1: number, num2: number):number {
return num1 + num2
}
function printPoint(point: {x: number, y: number}) {
console.log(point.x);
console.log(point.y)
}
printPoint({x: 123, y: 321})
const names = ["abc", "cba", "nba"]
names.forEach(function(item) {
console.log(item.split(""))
})
- 对象类型也可以指定哪些属性是可选的,可以在属性的后面添加一个“?”
function printPoint(point: {x: number, y: number, z?: number}) {
console.log(point.x)
console.log(point.y)
console.log(point.z)
}
printPoint({x: 123, y: 321})
printPoint({x: 123, y: 321, z: 111})
function printID(id: number | string | boolean) {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id);
}
}
printID(123);
printID("abc");
printID(true);
使用联合类型后因为一个参数可以取多个类型,所以需要先确定类型(即缩小类型),才能调用每个类型独有的方法与属性; 下面是类型缩小的几种方式:
type IDType = number | string;
function printID(id: IDType) {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id);
}
}
type Direction = "left" | "right" | "top" | "bottom";
function printDirection(direction: Direction) {
}
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);
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);
12、类型断言(缩小类型范围)
const el = document.getElementById("why") as HTMLImageElement;
el.src = "url地址";
class Person {}
class Student extends Person {
studying() {}
}
function action(p: Person) {
(p as Student).studying();
}
const stu = new Student();
action(stu);
二、各种操作符
1、! 非空断言操作符
x! 将从 x 值域中排除 null 和 undefined;
function myFunc(maybeString: string | undefined | null) {
const onlyString: string = maybeString;
const ignoreUndefinedAndNull: string = maybeString!;
}
2、可选链"?."
遇到null或者undefined时可以立即停止表达式的运行
const val = a?.b;
var val = a === null || a === void 0 ? void 0 : a.b;
如果a为null或者void 0,会直接返回void 0,而不会接着执行a.b; 因此,以后我们可以不需要编写形如
if( a && a.b){
}
这样的保护性代码。更好的写法是:
if( a?.b){
}
唯一需要注意的是,?. 与 && 运算符并不100%等价。&& 专门用于检测 falsy 值,比如空字符串、0、NaN、null 和 false 等。而 ?. 只会验证对象是否为 null 或 undefined,对于 0 或空字符串来说,并不会出现 “短路”;
三、函数详解
1、函数的可选类型
type SubtractsFnType = (num1: number, num2?: number) => number
const subtracts: SubtractsFnType = (a1: number, a2?: number) => {
if (a2) {
return a1 - a2
} else {
return a1
}
}
console.log(subtracts(5));
console.log(subtracts(5, 1));
export{}
2、函数的默认值
function foo(y: number, x: number = 20) {
console.log(x, y)
}
foo(30)
export{}
3、函数的剩余参数
function sum(initalNum: number, ...nums: number[]) {
let total = initalNum
for (const num of nums) {
total += num
}
return total
}
console.log(sum(20, 30))
console.log(sum(20, 30, 40))
console.log(sum(20, 30, 40, 50))
4、this相关
const info = {
name: "why",
eating() {
console.log(this.name + " eating")
}
}
info.eating()
export {}
type ThisType = { name: string };
function eating(this: ThisType, message: string) {
console.log(this.name + " eating", message);
}
const info = {
name: "why",
eating: eating,
};
info.eating("哈哈哈");
eating.call({name: "kobe"}, "呵呵呵")
eating.apply({name: "james"}, ["嘿嘿嘿"])
5、函数重载
在TypeScript中,如果我们编写了一个add函数,希望可以对字符串和数字类型进行相加,应该如何编写呢?
- 通过类型缩小
function add(a1: number | string, a2: number | string) {
if (typeof a1 === "number" && typeof a2 === "number") {
return a1 + a2
} else if (typeof a1 === "string" && typeof a2 === "string") {
return a1 + a2
}
}
add(10, 20)
- 通过函数重载
function add(num1: number, num2: number): number;
function add(num1: string, num2: string): string;
function add(num1: any, num2: any): any {
if (typeof num1 === "string" && typeof num2 === "string") {
return num1.length + num2.length;
}
return num1 + num2;
}
const result = add(20, 30);
const result2 = add("abc", "cba");
console.log(result);
console.log(result2);
export {};
|