一、typeof
TS 中的 typeof ,书写的位置在类型约束的位置上,表示获取某个数据的类型。
const a: string = 'asd'
let b: typeof a = "asdfg"
console.log(a,b); // asd asdfg
让 b 这个变量保持与 a 的类型一致。
当 typeof 作用于类的时候,得到的类型,是该类的构造函数。
将参数或者变量约束为构造函数时可以这样写:
class Users {
loginid: string = 'admin'
loginpsw:string = '123456'
}
function createUser(cls: typeof Users):Users {
return new cls()
}
const u1 = createUser(Users)
Users // 代表类本身;
new Users // 代表类的构造函数。
这里的 typeof Users 代表的是类本身,而不是类的构造函数。
二、keyof
作用于类、接口、类型别名,用于获取其他类型中的所有成员名组成的联合类型
interface Users {
loginid: string
loginpsw: string
}
function print(obj: Users, prop: keyof Users) {
console.log(obj[prop]);
}
const u1: Users = {
loginid: "admin",
loginpsw: "123456",
}
print(u1,"loginid") // admin
可以通过 keyof 关键字取出某些类型里的成员,组成联合类型。
三、in
该关键字往往和 keyof 联用,限制某个索引类型的取值范围。
type Obj = {
[p in "loginid" | "loginpsw"]: string
}
// 等效于
type Obj = {
loginid: string
loginpsw: string
}
以上两种方式效果一致。
与 keyof 联用:相当于将接口 Users 中的所有属性值类型变成字符串,得到一个新类型,拿来给类型别名 Obj 用。
interface Users {
loginid: string
loginpsw: string
}
type Obj = {
[p in keyof Users]: string
}
const u2: Obj = {
loginid: "admin",
loginpsw: "123456",
}
console.log(u2); // { loginid: 'admin', loginpsw: '123456' }
将类型别名的属性和属性类型与接口一致:
interface Users {
loginid: string
loginpsw: string
age: number
}
type Obj = {
[p in keyof Users]: Users[p]
}
const u2: Obj = {
loginid: "admin",
loginpsw: "123456",
age: 18
}
console.log(u2); // { loginid: 'admin', loginpsw: '123456', age: 18 }
如果想使用多个接口类型,可以使用泛型:
interface Users {
loginid: string
loginpsw: string
age: number
}
type Obj<T> = {
readonly [p in keyof T]?: T[p]
}
const u2: Obj<Users> = {
loginid: "admin",
age: 18
}
console.log(u2); // { loginid: 'admin', age: 18 }
此时类型别名 Obj 中的属性都是可选并且只读的,重新赋值会报错。