1. 八种基本类型
string、number、boolean、undefined、null、object、bigint、symbol
与JavaScript相同
let str: string = "jimmy";
let num: number = 24;
let bool: boolean = false;
let u: undefined = undefined;
let n: null = null;
let obj: object = {x: 1};
let big: bigint = 100n;
let sym: symbol = Symbol("me");
1.1. 注意点:
- null和undefined可以赋值给任何类型,即null和undefined是任何类型的子类型。
- number和bigint都表示数字,但是这两种类型并不兼容。
2. 其他特殊类型
2.1. 数组
数组的定义方法:
const list1: number[] = [1, 2, 3];
// 泛型的定义方法
const list2: Array<number> = [1,2,3];
// 数组元素的具体类型定义方法
const list3: [number, string, boolean] = [1, '2', true];
// 数组对象的对象方法
const list4: [{name: string, age: number}] = [{name: 'jack', age: 18}];
// 采用泛型的定义方法
const list5: Array<{name: string, age: number}> = [{name: 'jack', age: 30}];
// 接口的定义方法,对象中的属性过多的时候可采用
interface User{
name: string,
age: number
}
const list6: Array<User> = [{name: 'jack', age: 30}];
export default {}
2.2. 函数
函数的定义方法:
// 函数声明式
function sum(x: number, y: number): number {
return x + y;
}
// 函数表达式
const sum = (x:number, y:number): number=>{
return x + y;
}
// 函数表达式另一种写法 斜括号看作一个整体
const sum:/(x: number, y:number) => number/ = (x, y) =>{
return x + y;
}
// 参数可选 参数默认值 剩余参数
1. function buildName(firstName: string, lastName?: string){}
2. function buildName(firstName: string, lastName: string = 'Cat'){}
3. function push(array: any[], ...items: any[]){}
2.3. void
void表示没有任何类型,不能直接赋值。
let a: void;
let b: number = a; // 报错
2.4. never
never表示用不存在的值的类型。
值永不存在的两种情况:
// 异常
function err(msg: string): never { // OK
throw new Error(msg);
}
// 死循环
function loopForever(): never { // OK
while (true) {};
}
实践使用:never可以用于避免出现新增了联合类型,提示报错,保证函数返回值的类型控制在正确的范围内。
type Foo = string | number;
function controlFlowAnalysisWithNever(foo: Foo) {
if (typeof foo === "string") {
// 这里 foo 被收窄为 string 类型
} else if (typeof foo === "number") {
// 这里 foo 被收窄为 number 类型
} else {
// foo 在这里是 never
const check: never = foo;
}
}
2.5. any
any类型是任何类型的父类型,any类型允许被赋值任何类型。
但是any类型不太安全,不太推荐使用该类型。
let a: any = 666;
a = "Semlinker";
a = false;
a = 66
a = undefined
a = null
a = []
a = {}
2.6. unknow
unknown与any一样,所有类型都可以分配给unknown,反之把unknown 赋值给其它类型会报错。
// unknown 可以接收任意类型
let name:string = "jack"
let user:unknown = name;
// unknown 不可以赋值给其它类型,any除外,下面会报错
let name:unknown = "jack"
let user:string = name;
3. 交叉类型
交叉类型通常用于多个接口合并成一个类型,从而实现等同接口继承的效果,也就是合并接口类型。
type User = { name: string }
type AgeType = { age: number }
let jack: User & AgeType = { name:'jack', age: 30 }
注意:如果多个接口类型存在同名属性,比如一个是number,一个string类型,那么合并出来的是无用类型。
type obj = { id: number; name: string; }
& { age: number; name: number; };
const mixed: obj = {
id: 1,
name: 2, // ts(2322) 错误,'number' 类型不能赋给 'never' 类型
age: 2
};
如果两个类型中,一个类型是另一个类型的子类型(字面量类型)那么会选择他们的子类型。
4. 联合类型
联合类型表示取值可以为多种类型中的一种,使用|来分割每一个类型
let num:string | number
num = '7'
num = 7
5. 接口
接口是对类的一部分行为进行抽象,也可以对对象的形状进行描述。
// 抽象一个Person类,参数必须与该类相同
interface Person {
readonly name: string; // 表示该属性是只读属性赋值会报错
age: number;
}
const jack:Person = {
name: 'Jack',
age:30
}
// 少字段会报错
const tom:Person = {
name: 'Tom',
}
// 多字段也会报错
const tom:Person = {
name: 'Tom',
age: 30,
money: 100
}
也可以使用允许其他的任意属性,可以使用索引标签的形式来满足要求。需要注意的是一旦定义了任意属性,确定属性和可选属性的类型都必须是它的类型的子集。
// 基本写法
interface Person {
name: string;
age?: number;
// [propName: string]: string // 可选属性必须是必选属性的子类型
[propName: string]: string | number | undefined
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
// 报错 Property 'age' of type 'number' is not assignable to string index type 'string'.
let jack: Person = {
name: 'jack',
age: 25,
gender: 'male'
}
接口继承的写法
interface User {
id: number;
name: string;
}
interface Person extends User {
age: number;
}
const Tom:Person = {
id: 1,
name: 'tom',
age: 30
}
接口与类型的区别:
- 接口通过interface定义,type用来定义类型的别名。
- 接口可以重定义,type不行。接口重复定义时,后者接口是对前者接口的一种补充。
- 接口可以使用extends进行继承,type可以通过联合类型来模拟继承。
6. 泛型
泛型就是当定义变量无法确定其类型时,可以采用泛型的方法。
function identity<T>(value:T):T{
return value;
}
identity<number>(1)
identity<string>('jack')
理解如下:
传递多个参数类型:
function identity<T,U>(x:T,y:U):T{
return x;
}
identity<number,number>(1,2)
identity<string,number>('a',2)
也可以对泛型的参数类型进行约束
interface Sizeable{
size: number
}
function identity<T extends SizeAble>(arg: T):T{
console.log(arg.size)
return arg
}
更多泛型用法可以参考文章:juejin.cn/post/701880…
7. 总结
7.1. 基本类型总结
- 能确定类型的,尽量定义类型。
- 无法确定类型的,可以使用 any 进行兜底。
- 当函数没有返回值时,可以使用void定义。
- any和unknown可以接收任意类型值,any可以赋值给任意类型,但unknown不可以赋值给任意类型。
- void和any在项目中是比较常见的,never和unknown不常用。就比如,最近在调试PC端渲染组件的时候,会经常碰到。
8. 参考文章
- TypeScript官方文档:www.typescriptlang.org/zh/
- TypeScript史上最强入门文章:juejin.cn/post/701880…