TS(TypeScript) 是 JavaScript 的超集,赋能 JS 类型。
- 代码既文档
- 编译器自动提示
泛型
首先需要明确一点,用 TS 写不代表 TS 支持友好。
function identity0(arg: any): any {
return arg;
}
let str0 = identity0("typescript"); // let str0: any
let num0 = identity0(1); // let num0: any
想要实现正确的类型推导,就得使用泛型 👇
// 相当于 type T = arg 的类型
function identity<T>(arg: T): T {
return arg;
}
let str = identity<string>("typescript"); // let str: string
let num = identity<number>(1); // let num: number
keyof
keyof关键字:拆解已有类型
interface VueCourse5 {
name: string;
price: number;
}
type CourseProps = keyof VueCourse5; // 只能是name和price选一个
let k: CourseProps = "name";
let k1: CourseProps = "pric"; // Type '"pric"' is not assignable to type 'keyof VueCourse5'. Did you mean '"price"'?
extends
extends关键字:条件判断
type ExtendsType<T> = T extends boolean ? "重学前端" : "玩转Vue 3";
type ExtendsType1 = ExtendsType<boolean>; // type ExtendsType1='重学前端'
type ExtendsType2 = ExtendsType<string>; // type ExtendsType2='玩转Vue 3'
in
in关键字:循环
type Courses = "VUE" | "JS";
type CourseObj = {
[k in Courses]: number; // 遍历Courses类型作为key
};
// 上面的代码等于下面的定义
// type CourseObj = {
// VUE: number;
// JS: number;
// }
infer
infer关键字:进一步判断
type Foo = () => CourseObj;
// 如果T是一个函数,并且函数返回类型是P就返回P
type ReturnType1<T> = T extends () => infer P ? P : never;
type Foo1 = ReturnType1<Foo>;
实战
看懂 TS 🥳
// K extends keyof T限制K的类型必须是T的属性之一
// T[K]是值的类型
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
return o[name];
}
const coursePrice: CourseObj = {
VUE: 129,
TS: 129,
};
getProperty(coursePrice, "VUE");
getProperty(coursePrice, "TS");
定义接口
需求:定义 Todo 类型,字段可选。
interface Todo {
title: string;
desc: string;
done: boolean;
}
type Partial1<T> = {
[K in keyof T]?: T[K];
};
type partTodo = Partial1<Todo>;
Interface API
需求:规范接口,友好提示。
// import axios from "axios";
const axios = {
post(url, obj) {
let xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
return xhr.responseText;
}
}
};
xhr.send(obj);
},
};
// 如果 message必传 怎么提醒缺少参数
// 接口不存在 类型需要怎么报错
interface Api {
"/course/buy": {
id: number;
};
"/course/comment": {
id: number;
message: string;
};
}
function request<T extends keyof Api>(url: T, obj: Api[T]) {
return axios.post(url, obj);
}
request("/course/buy", { id: 1 });
request("/course/comment", { id: 1, message: 2 }); // Type 'number' is not assignable to type 'string'.
request("/course/comment", { id: 1 }); // Argument of type '{ id: number; }' is not assignable to parameter of type '{ id: number; message: string; }'.
request("/course/404", { id: 1 }); // Argument of type '"/course/404"' is not assignable to parameter of type 'keyof Api'.