您现在的位置是:首页 >技术教程 >TypeScript类型注释网站首页技术教程
TypeScript类型注释
1.类型注释的种类
typescript使用类型注释来进行静态类型检查
JavaScript类型(number,string,boolean,bigInt,symbol,null,undefined,object)
JavaScript内置类(Number,String,Object,Function,等等)
JavaScript具体值(1,“123”,{name: ‘Danny’},等等)
自定义类型(自定义类,类型别名,接口)
数组(一维数组,二维数组,等等)
元组([某种类型,某种类型,等等])
特殊类型(void,enum,never,any,联合类型,合并类型)
1.1 注释:JavaScript类型和JavaScript内置类
其中基本类型正常注释即可,选择大小写均可。对于引用类型需要特别注意。
1.1.1 注释:Object
-
如果使用Object或object注释:(1)则会认为对象是空对象,不可以对其属性进行改查。(2)宽松地类型检查,声明obj时赋初始值,属性任何类型都是合理的
const obj: Object = { school: 'SDU', age: 21 }
-
(推荐使用)如果使用对象字面量进行注释:(1)则会认为对象是灵活的,可以对其属性进行改查。(2)正常的类型检查,obj赋值时,属性必须严格对照注释
const obj: { school: String, age: Number } = { school: 'SDU', age: 21 }
1.1.2 注释:Function
注释Function分为箭头函数和普通函数注释。注释为箭头函数时,在箭头后写明返回值。注释为普通函数时在括号后写明返回值。
-
如果使用Function注释,效果同上。
const func: Function = (arg1: string, arg2: number) => { console.log(123) }
-
(推荐使用)如果使用函数字面量进行注释,效果同上。
const func: (arg1: string, arg2: number) => void = function(arg1: string, arg2: number) { console.log(123) }
1.2 注释:JavaScript具体值
当声明时指定了具体值之后,变量赋值只能赋为该值,否则会发生错误
let variableA: 2
variableA = 2
1.3 注释:自定义类型
1.3.1 注释:自定义类
class Test {}
let variable: Test
1.3.2 注释:类型别名
使用类型别名指定已经存在的类型
type School = {
name: String,
age: Number
}
let variable: School
1.3.3 注释:接口
使用接口指定映射类型
interface School = {
name: String,
age: Number
}
let varibale: School
1.3.4 接口和类型别名的区别
区别主要发生在接口和类型别名都表示映射类型时。
-
扩展属性的方法不同
-
接口可以像类一样通过继承扩展属性
interface A { name: string } interface B extends A { gender: string } let obj: B = { name: "Danny", gender: "male" }
-
接口可以使用&运算符扩展属性
interface A { name: string } interface B { gender: string } type Type = A & B
-
接口可以直接扩展属性
interface A { name: string } interface A { gender: string } let obj: A = { name: "Danny", gender: "male" }
-
类型别名只能通过&运算符扩展属性
type A = { name: string } type B = { gender: string } type C = A & B
-
-
可修改性不同
- 接口创建后可以通过覆写来添加新的属性
- 类型别名创建后不能在原有类型上添加新的属性
1.4 注释:数组
let ar1Dim: string[]
let ar2Dim: string[][]
1.5 注释:元组
元组确定了数组每个元素的类型以及数组的长度
let tuple: [string, number, boolean]
1.6 注释:特殊类型
1.6.1 注释:枚举
使用enum声明一个枚举,枚举中又声明了若干枚举值,每一个枚举值又会有一个关联值。
1.6.1.1 默认枚举
默认从第一个枚举值开始关联0,往后关联1,2,3
enum Fruit {
Apple,
Orange,
Melon
}
typescript的默认枚举在实现上实际是一个对象,对象中进行了反向映射
let Fruit = {
Apple: 0,
Orange: 1,
Melon: 2,
'0': 'Apple',
'1': 'Orange',
'2': 'Melon'
}
Fruit.Apple
或Fruit[0]
这两种访问形式都有应用场景
1.6.1.2 数值枚举
数值枚举要求给枚举值赋值为数值
enum Fruit {
Apple = 2,
Orange,
Melon
}
反向映射结果为
let Fruit = {
Apple: 2,
Orange: 3,
Melon: 4,
'2': 'Apple',
'3': 'Orange',
'4': 'Melon'
}
也可以给全部枚举值指定关联值
enum Fruit {
Apple = 2,
Orange = 1,
Melon = 4
}
反向映射结果为
let Fruit = {
Apple: 2,
Orange: 1,
Melon: 4,
'2': 'Apple',
'1': 'Orange',
'4': 'Melon'
}
1.6.1.3 字符串枚举
字符串枚举要求每个枚举值必须赋一个字符串关联值
enum Fruit {
Apple = 'Apple',
Orange = 'Orange',
Melon = 'Melon'
}
反向映射结果为
let Fruit = {
Apple: 'Apple',
Orange: 'Orange',
Melon: 'Melon',
}
1.6.1.4 异构枚举
异构枚举要求每个枚举值必须赋一个字符串或数值关联值。不推荐使用异构枚举,一般枚举值都有相关性,异构枚举破坏了相关的联系。
enum Fruit {
Apple = 0,
Orange = 'Orange',
Melon = 'Melon'
}
反向映射结果为
let Fruit = {
Apple: '0',
0: 'Apple',
Orange: 'Orange',
Melon: 'Melon'
}
1.6.1.5 常量枚举
常量枚举在编译时会被删除,不产生枚举对应的对象形式。因此声明常量枚举后直接访问枚举是非法的,只能访问枚举值。
const enum Fruit {
Apple,
Orange,
Melon
}
console.log(Fruit) // 非法的
console.log(Fruit.Apple) // 合理的
因为不会生成对象形式,因此最后结果只会输出0
1.6.1.6 何时使用枚举
在typescript中枚举,数组,对象相互之间的功能比较相似,需要在特定场景进行分析。
-
语意明确时用枚举: 当常量具有清晰明确的语意时,应该使用枚举类型。枚举类型为常量提供了明确的命名和类型,可以使代码更加可读和维护。
enum DaysOfWeek { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } function isWeekend(day: DaysOfWeek): boolean { return day === DaysOfWeek.Saturday || day === DaysOfWeek.Sunday; } isWeekend(DaysOfWeek.Saturday); // true
-
值不需要变动用对象或数组: 如果固定的值不会发生变化,可以考虑使用常量数组或对象。
const weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]; const maxFileSize = { txt: 1024, jpg: 2048, gif: 3072 };
-
值需要从动态来源获得用对象或数组:如果值需要从动态来源获取,例如从后端API中获取,则应该使用对象或数组类型,并根据需要进行类型定义。
interface User { id: number; name: string; role: "admin" | "member"; } function hasAdmin(users: User[]) { return users.some(user => user.role === "admin"); } // 从API中获取用户信息 fetch("/users") .then(response => response.json()) .then(data => { if (hasAdmin(data)) { // do something } });
1.6.1.7 注释:枚举
枚举和枚举值都可以作为类型来进行注释。
将变量注释为枚举类型,指的是变量的取值范围固定在枚举值的关联值当中。
let variableEnum: Fruit = 0
if(variableEnum === Fruit.Apple)
console.log('Apple')
else if(variableEnum === Fruit.Orange)
console.log('Orange')
else if(variableEnum === Fruit.Melon)
console.log('Melon')
else
console.log('None')
将变量注释为枚举值类型,指的是变量只能取枚举值的关联值。
let variableA: Fruit.Apple
variableA = 0
1.6.2 注释:联合类型,合并类型
联合类型指的是用|来表示变量可以取不同的类型
let variableA: string | number | boolean
合并类型指的是用&来表示变量取多种类型中的交集。
-
对于接口,对象字面量类型,使用&合并会合并属性,因为可以做到同时满足。
interface A { name: string } interface B { gender: string } type C = A & B let obj: C = { name: 'Danny', gender: 'male' }
-
对于普通类型,使用&合并会直接取交集,因为无法同时满足。
type TypeA = string | number type TypeB = number | boolean type TypeC = TypeA & TypeB let variable: TypeC = 123 // variable只能取数值类型
1.6.3 注释:any,never,void
any表示任何类型,不推荐使用,使用后效果和JavaScript相同。
never表示不能取到的类型,例如使用合并类型时为空集,那么就是never类型。
type Type = string & number // Type就是never类型,没有任何一种类型可以既是string又是number
let empty: () => never // empty无法被赋值,因为函数默认返回undefined,存在返回值
void表示返回值为undefined的情景。用于函数返回值时never比void更严格。
let empty: () => void = () => {} // empty可以被赋值,因为void类型允许返回undefined
2.类型注释的场景
声明变量
let name: String
let func: Function
声明函数
function func(): void {}
function func2(): Number {
return 123
}
const func3: () => void = () => {}
声明形参
function func(name: String, age: Number): void {}
声明解构
const { school, age } : { school: String, age: Number } = obj