Appearance
基本类型
1.类型声明
类型声明是TS非常重要的一个特点
通过类型声明可以指定TS中变量(参数、形参)的类型
指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值
语法:
typescript
let 变量: 类型;
let 变量1: 类型 = 值;
function fn(参数: 类型, 参数: 类型): 类型 {
...
}2.自动类型判断
- TS拥有自动的类型判断机制
- 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
- 所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明
3.类型:
| 类型 | 例子 | 描述 |
|---|---|---|
| number | 1, -33, 2.5 | 任意数字 |
| string | 'hi', "hi", hi | 任意字符串 |
| boolean | true、false | 布尔值true或false |
| 字面量 | 其本身 | 限制变量的值就是该字面量的值 |
| any | * | 任意类型 |
| unknown | * | 类型安全的any |
| void | 空值(undefined) | 没有值(或undefined) |
| never | 没有值 | 不能是任何值 |
| object | {name:'孙悟空'} | 任意的JS对象(引用类型) |
| Object | * | 所有类型 |
| array | [1,2,3] | 任意JS数组 |
| tuple | [4,5] | 元素,TS新增类型,固定长度数组 |
| enum | enum{A, B} | 枚举,TS中新增类型 |
number
typescript
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;boolean
typescript
let isDone: boolean = false;string
typescript
let color: string = "blue";
color = 'red';
let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.
I'll be ${age + 1} years old next month.`;字面量
也可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围
typescript
let color: 'red' | 'blue' | 'black';
let num: 1 | 2 | 3 | 4 | 5;
#也可以定义类型选择
let a: string | booleanany
typescript
let d: any = 4;
d = 'hello';
d = true;unknown
只能赋值给自身,或者赋值给any
unknown的对象中,没有办法读取到任何属性,方法也不可以调用
typescript
let notSure: unknown = 4;
notSure = 'hello';void
typescript
let unusable: void = undefined;never
将使用 never 类型来表示不应该存在的状态
typescript
// 返回never的函数必须存在无法达到的终点
// 因为必定抛出异常,所以 error 将不会有返回值
function error(message: string): never {
throw new Error(message);
}
// 因为存在死循环,所以 loop 将不会有返回值
function loop(): never {
while (true) {
}
}never 与 void 的差异
ts
//void类型只是没有返回值 但本身不会出错
function Void(): void {
console.log();
}
//只会抛出异常没有返回值
function Never(): never {
throw new Error('aaa')
}差异2 当我们鼠标移上去的时候会发现 只有void和number never在联合类型中会被直接移除
ts
type A = void | number | nevernever 类型的一个应用场景
ts
type A = '唱' | '跳' | 'rap'
function Kun(value: A) {
switch (value) {
case "唱":
break
case "跳":
break
case "rap":
break
default:
//是用于场景兜底逻辑
const error: never = value;
return error
}
}如果新增了一个篮球,我们必须手动找到所有 switch 代码并处理,否则将有可能引入 BUG 。 而且这将是一个“隐蔽型”的BUG,如果回归面不够广,很难发现此类BUG。
ts
type A = '唱' | '跳' | 'rap' | '篮球'
function Kun(value: A) {
switch (value) {
case "唱":
break
case "跳":
break
case "rap":
break
case "篮球":
break
default:
//是用于场景兜底逻辑
const error: never = value;
return error
}
}由于任何类型都不能赋值给 never 类型的变量,所以当存在进入 default 分支的可能性时,TS的类型检查会及时帮我们发现这个问题
object(没啥用)
typescript
let obj: object = {};Object
typescript
let obj: Object = 123;
let obj1: Object = '123';
let obj2: {} = 123 // new Object
let obj3: {} = {name: 'zs'} // 无法对内部进行修改
// obj3.age = 12 会报错array
typescript
let list: number[] = [1, 2, 3];
// 数组泛型
let list1: Array<number> = [1, 2, 3];
#元组(固定长度的数组)
let list2: [string, string]
h = ['hello', 'nihao']用接口表示数组
一般用来描述类数组
ts
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
//表示:只要索引的类型是数字时,那么值的类型必须是数字。多维数组
ts
let data: number[][] = [[1, 2], [3, 4]];arguments类数组(伪数组)
ts
function Arr(...args: any): void {
console.log(arguments)
//错误的 arguments是类数组不能这样定义 //
let arr: number[] = arguments
}
Arr(111, 222, 333)
function Arr(...args: any): void {
console.log(arguments)
//ts内置对象IArguments 定义
let arr: IArguments = arguments
}
Arr(111, 222, 333)
//其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}TIP
这也是伪数组
let list = document.querySelectorAll('div')
any 在数组中的应用
一个常见的例子数组中可以存在任意类型
ts
let list: any[] = ['test', 1, [], {a: 1}]tuple(元组)
元组是固定数量的不同类型的元素的组合
typescript
let x: [string, number];
x = ["hello", 10];enum
TS新增-枚举
默认从0开始
typescript
enum Color {
Red, //0
Green, //1
Blue, //2
}
enum Color {
Red = 1,
Green, //2
Blue, //3
}
enum Color {
Red = 1,
Green = 2,
Blue = 4,
}字符串枚举
ts
enum Color {
Red = 'red',
Green = 'green',
Blue = 'blue',
}异构枚举
可以混合字符串和数字成员
ts
enum Color {
Red = 'red',
Green = 'green',
Blue = 'blue',
}接口枚举
定义一个枚举Types 定义一个接口A 他有一个属性red 值为Types.yyds
声明对象的时候要遵循这个规则
ts
enum Types {
yyds,
dddd
}
interface A {
red: Types.yyds
}
let obj: A = {
red: Types.yyds
}const枚举
let 和 var 都是不允许的声明只能使用const
大多数情况下,枚举是十分有效的方案。 然而在某些情况下需求很严格。 为了避免在额外生成的代码上的开销和额外的非直接的对枚举成员的访问,我们可以使用 const枚举。 常量枚举通过在枚举上使用 const修饰符来定义
const 声明的枚举会被编译成常量
ts
const enum Types {
no = "No",
yes = 'Yes'
}
console.log(Types.yes)
console.log(Types.no)在编译成js文件后内容为:
js
console.log("Yes" /* Types.yes */);
console.log("No" /* Types.no */);普通声明的枚举编译完后是个对象
ts
enum Types {
no = "No",
yes = 'Yes'
}
console.log(Types.yes)
console.log(Types.no)在编译成js文件后内容为:
js
var Types;
(function (Types) {
Types["no"] = "No";
Types["yes"] = "Yes";
})(Types || (Types = {}));
console.log(Types.yes);
console.log(Types.no);反向映射
它包含了正向映射( name -> value)和反向映射( value -> name)
要注意的是 不会为字符串枚举成员生成反向映射。
ts
enum Types {
success // 0
}
let successVal: number = Types.success
console.log(successVal) //0
let key = Types[successVal]
console.log(key) // success