数据类型我们需要使用小写形式,也就是boolean、number、string
,不要写成了Boolean、Number、String
这种。
Boolean、Number、String
是 JavaScript
的构造函数,比如我们用 Number
用于数字类型转化或者构造 Number
对象用的。而 TypeScript
中的 number
类型仅仅是表示类型,两者完全不同。
基本简单类型
TypeScript
支持js
中的七种简单数据类型。
数字 number
const decLiteral: number = 6
const hexLiteral: number = 0xf00d
const binaryLiteral: number = 0b1010
const octalLiteral: number = 0o744
字符串 string
const str: string = "randy";
布尔类型 boolean
const b: boolean = true;
null
let n: null = null;
默认情况下null
是只能赋值给null
类型的变量的。但是当我们在tsconfig.json
设置strictNullChecks: false
后 null
可以赋值给任何类型的变量。
// null和undefined赋值给string
let str:string = "哈哈";
str = null
let bool1: boolean = true;
bool1 = null
undefined
let u: undefined = undefined;
默认情况下 undefined
是所有类型的子类型。就是说你可以把 undefined
赋值给其他类型。
// null和undefined赋值给string
let str:string = "哈哈";
str= undefined
let bool1: boolean = true;
bool1= undefined
symbol
const sym: symbol = Symbol("name");
bigint
使用 BigInt
需要在 tsconfig.json
中给 lib
选项添加 "ESNext"
。
const big: bigint = BigInt("1111111111111111");
在TypeScript
中,number
类型虽然和 BigInt
都是有表示数字的意思,但是实际上两者类型是不同的:
let foo: number;
let bar: bigint;
foo = bar; // error: Type 'bigint' is not assignable to type 'number'.
bar = foo; // error: Type 'number' is not assignable to type 'bigint'.
复杂数据类型
object
object
表示非原始类型,也就是除 number,string,boolean,symbol,null,undefined
之外的类型。
// 对象类型
const user: {
name: string;
age: number;
} = { name: "randy", age: 25 };
// 类
class Person {}
const myPeople: Person = new Person();
跟js
中是一样的,引用类型都可以是object
类型
let value: object
value = new Date()
value = [1]
value = [1, 'hello']
数组 number[]
或者 Array<number>
这里的 number
只是举个例子,可以有其他类型比如 string、any
等。
const arr1: number[] = [1, 2, 3];
const arr2: Array<number> = [4, 5, 6];
// 这里用到了联合类型,后面会说
const arr3: (string | number)[] = [123, "randy"];
const arr4: Array<string | number> = [456, "demi"];
// 存对象
const arr5: { name: string; age: number }[] = [{ name: "randy", age: 25 }];
// 或者使用类型别名 type
type User = { name: string; age: number };
const arr6: User[] = [{ name: "demi", age: 25 }];
// 二维数组
const erweiArr: [][] = [
[1, 2, 3],
[4, 5, 6],
];
元组 Tuple
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同,但是顺序和个数不能变。
let x: [string, number];
// 这样是可以的
x = ["hello", 10];
// 这样是错的
x = [10, 'hello']
枚举 enum
枚举 enum
类型是对 JavaScript
标准数据类型的一个补充。
enum Color {
Red,
Green,
Blue,
}
//返回的是下标 类似数组下标从 0 开始 也可以赋初始值 Red=10 等这样返回的就是 11
let c1: Color = Color.Red;
console.log(c1); // 0
let c2: Color = Color.Green;
console.log(c2); // 1
// 我们还可以通过下标访问
console.log(Color[0] === "Red"); // true
console.log(Color[1] === "Green"); // true
我们还可以设置枚举的值是字符串,但是设置之后,通过下标的方式就获取不到值了。
enum Direction {
LEFT = "left",
RIGHT = "right",
}
console.log(Direction.LEFT); // left
console.log(Direction.RIGHT); // right
console.log(Direction[0]); //undefined
console.log(Direction[1]); //undefined
any
我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。那么我们可以使用 any
类型来标记这些变量。
变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型。
let notSure: any = 72;
notSure = "maybe a string instead";
记住any
类型是多人协作项目的大忌,很可能把Typescript
变成AnyScript
,通常在不得已的情况下,不应该首先考虑使用此类型。
unknown
unknown
是 TypeScript 3.0
引入了新类型,是 any
类型对应的安全类型。
虽然它们都可以是任何类型,但是当 unknown
类型被确定是某个类型之前,它不能被进行任何操作比如实例化、getter、函数执行
等等。
let value: any;
value = true; // OK
value = 1; // OK
value = "Hello World"; // OK
value = Symbol("type"); // OK
value = {} // OK
value = [] // OK
let value2: unknown;
value = true; // OK
value = 1; // OK
value = "Hello World"; // OK
value = Symbol("type"); // OK
value = {} // OK
value = [] // OK
let value3: any;
value3.foo.bar; // OK
value3(); // OK
new value3(); // OK
value3[0][1]; // OK
let value4: unknown;
value4.foo.bar; // ERROR
value4(); // ERROR
new value4(); // ERROR
value4[0][1]; // ERROR
void
void
申明变量或函数。
当一个函数没有返回值时,你可以申明类型为 void
。
// 没有返回值的函数
function sayName(): void {
console.log("randy");
}
当变量申明为 void
的时候只能为它赋予 undefined
。
const u: void = undefined;
当然,当我们在tsconfig.json
设置strictNullChecks: false
后 null
可以赋值给任何类型的变量。也就可以赋值给void
类型的变量。
const n: void = null;
never
never
类型表示的是那些永不存在的值的类型。用得少(死循环或者抛出异常)
function whileTrueFun(): never {
while (true) {}
}
function throwErrorFun(): never {
throw new Error("自定义错误呢");
}
// 空数组,而且永远是空的
const empty: never[] = []
高级类型
联合类型 |
当 TypeScript
不确定一个变量类型的时候可以使用联合类型。使用|
定义。
但是我们只能访问此联合类型的所有类型里共有的属性或方法。
类似js
里面或的意思,就是多种类型中选择一种。
let myFavoriteNumber: string | number = 123;
myFavoriteNumber = "randy";
交叉类型 &
交叉类型是将多个类型合并为一个类型。通过 &
定义。
类似js
里面与的意思,就是多种类型的结合。
type Flag1 = { x: number };
type Flag2 = { y: string };
type Flag3 = Flag1 & Flag2;
let flag: Flag3 = {
x: 1,
y: "hello",
};
// 接口也支持
interface User1 {
name: string;
}
interface User2 {
age: number;
}
type User3 = User1 & User2;
const user: User3 = { name: "randy", age: 24 };
console.log(user);
字面量类型
在 TypeScript
中,字面量不仅可以表示值,还可以表示类型,即所谓的字面量类型。 目前,TypeScript
支持 3 种字面量类型:字符串字面量类型、数字字面量类型、布尔字面量类型,对应的字符串字面量、数字字面量、布尔字面量分别拥有与其值一样的字面量类型,具体示例如下:
let flag1: "hello" = "hello";
let flag2: 1 = 1;
let flag4: true = true;
虽然可以定义字面量类型,但是它的值却不能改变了,那这个字面量类型有啥用呢?
// 定义好之后就不能改变值了
// flag1 = 'randy' // error 不能将类型“"randy"”分配给类型“"hello"”。
// flag2 = 2 // error 不能将类型“2”分配给类型“1”
// flag4 = false // error 不能将类型“false”分配给类型“true”
字面量类型它真正的应用场景是可以把多个字面量类型组合成一个联合类型,用来描述拥有明确成员的实用的集合。
比如
type Direction2 = 'up' | 'down' ;
function move(dir: Direction2) {
// ...
}
move('up'); // ok
move('right'); // 类型“"right"”的参数不能赋给类型“Direction2”的参数
通过使用字面量类型组合的联合类型,我们可以限制函数的参数为指定的字面量类型集合,然后编译器会检查参数是否是指定的字面量类型集合里的成员。
因此,相较于使用 string
类型,使用字面量类型(组合的联合类型)可以将函数的参数限定为更具体的类型。这不仅提升了程序的可读性,还保证了函数的参数类型,可谓一举两得。
有没有感觉有点像简单版的枚举类型,哈哈。
条件类型
条件类型够表示非统一的类型,以一个条件表达式进行类型关系检测,从而在两种类型中选择其一:
T extends U ? X : Y
上面的代码可以理解为: 若 T
能够赋值给 U
,那么类型是 X
,否则为 Y
,有点类似于JavaScript
中的三元条件运算符。
比如我们声明一个函数 f
,它的参数接收一个布尔类型,当布尔类型为 true
时返回 string
类型,否则返回 number
类型。
declare function f<T extends boolean>(x: T): T extends true ? string : number;
const x = f(Math.random() < 0.5)
const y = f(false)
const z = f(true)
x y z
的类型分别如下:
对于extends
如果不熟悉的话可以先跳过,笔者后面讲泛型约束的时候会详细介绍。
系列文章
TypeScript入门之类型推断、类型断言、双重断言、非空断言、确定赋值断言、类型守卫、类型别名
后记
感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!