unknown类型
- unknown类型代表任何值,这与any类型类似,但更加安全,因为对未知unknown值做任何事情都是不合法的
- unknown类型被称为安全的any类型
unknown类型的使用
let str: unknown
str = 18
str = '数字化'
str = [1,2,4]
let vts: unknown
let nums: number
vts = 18
nums = vts as number
if(typeof vts == "number"){
nums = vts
}
- unknown与其他任何类型组成的交叉类型最后都是其他类型 & 交叉类型
type myType1 = number & unknown
type myType2 = boolean & unknown
let st: myType1 = 18
let sts:myType2 = true
- unknown除了与any以外,与其他任何类型组成的联合类型都是unknown类型
type MyType1 = unknown | any
type MyType2 = unknown | number
type MyType3 = unknown | string | boolean
let c: MyType1
let b: MyType2
let e: MyType3
type MyType6 = never extends unknown? true:false
map类型
- Map对象保存键值对,并且能够记住键的原始插入顺序
- 任何值(对象或原始值)都可以作为一个键或一个值
创建map
let myMap = new Map()
使用map
myMap.set("李子龙",12)
myMap.set('李小龙',22)
myMap.set('李耀龙',32)
myMap.get('李子龙')
myMap.has('李耀龙')
myMap.size
myMap.delete('李子龙')
myMap.clear()
myMap.delete('李子龙')
for (let key of myMap.keys()){
console.log(key)
}
for (let value of myMap.values()){
console.log(value)
}
for (let entry of myMap.entries()){
console.log(entry)
}
for (let [key,value] of myMap){
console.log(key,value)
}
索引类型
- 可以使用一个索引访问类型来查询另一个类型上的特定属性
- 格式: [key]
- 注意点: 不会返回null/undefined/never类型
使用
class Person{
name: string
age: number
constructor(name: string,age: number){
this.name = name
this.age = age
}
}
type MyType = Person['name']
let nu: MyType = '张三'
console.log(nu)
案例
let obj = {
name: '李四',
age: 18,
set: true
}
function getValues<T, K extends keyof T>(obj: T,keys: K[]): T[K][] {
let arr = [] as T[K][]
keys.forEach(key => {arr.push(obj[key])})
return arr
}
let res = getValues(obj,['name','age'])
条件类型
基本使用
type MyType<T> = T extends string? string : any
type res = MyType<number>
函数重载
interface IName{
name: string
}
interface IAge{
age: number
}
function reload(name: string): IName
function reload(age: number): IAge
function reload(nameorAge: string | number): IName | IAge
function reload(nameorAge: string | number): IName | IAge {
throw ""
}
条件类型优化函数重载
interface IName{
name: string
}
interface IAge{
age: number
}
type Condition<T> = T extends string? IName : IAge
function reload<T extends number | string>(nameorAge: T): Condition<T>{
throw ""
}
分布式条件类型
- 当条件类型作用域一个通用类型时,当给定的一个联合类型时,变成分布式
- 通常情况下,分布性是需要的行为,为了避免这种行为,可以使用方括号包围extends关键字的每一边
基础使用
type MyType<T> = T extends any? T : never
type res = MyType<string | number>
type resu = Exclude<string | number | boolean, boolean>
- 从中剔除null和undefined NonNullable
type resul = NonNullable<string | number | boolean | null | undefined>
type result = ReturnType<() => string>
- 获取一个类的构造函数组成的元组类型 ConstructorParamters
class Person {
constructor(name: string,age: number){}
}
type r = ConstructorParameters<typeof Person>
- 获取函数的参数类型组成的元组类型 Parameters
function show(name: string,age: number,sex: boolean){}
type re = Parameters<typeof show>
infer关键字推断
- 条件类型提供了一种方法来推断,在真实分支中使用infer关键字进行对比的类型
- 可以使用infer关键字编写一些有用的辅助类别名
infer简化操作
type ID = number[]
type IName = string[]
type Unpacked<T> = T extends IName? string : T extends ID? number : T
type nameType = Unpacked<IName>
type ElementOf<T> = T extends Array<infer E>? E : T
type res = ElementOf<string[]>
type res1 = ElementOf<number[]>
type res2 = ElementOf<boolean>
infer可以推断出联合类型
type Foo<T> = T extends {a: infer U;b: infer U} ? U : never
type res3 = Foo<{a: string;b: number}>
映射类型
- 当不想重复定义类型,一个类型可以以另一个类型为基础创建新类型
- Readonly / Partial关键字
- Record / Pick映射类型
- Readonly,Partial和Pick是同态的,但Record不是,因为Record并不需要输入类型来拷贝属性,所以它不属于同态
映射类型—只读
interface IPerson{
name: string
age: number
}
type ReadonlyTest<T> = {
readonly [P in keyof T]: T[P]
}
type res = ReadonlyTest<IPerson>
映射类型—可选
interface IPerson{
name: string
age: number
}
type PartialTest<T> = {
[P in keyof T]?: T[P]
}
type res1 = PartialTest<IPerson>
映射类型 +/-指定添加或删除
interface IPerson2 {
readonly name?: string
readonly age?: number
}
type Test<T> = {
-readonly [P in keyof T]-?: T[P]
}
type res2 = Test<IPerson2>
映射类型— Readonly/Partial
interface IPerson3 {
name: string
age: number
}
type res3 = Readonly<IPerson3>
type res4 = Partial<IPerson3>
映射类型—Record
type Name = "person" | "animal"
type Person = {
name: string
age: number
}
type NewType = Record<Name,Person>
let res: NewType = {
person: {
name: '法外狂徒张三',
age: 22
},
animal: {
name: '小白白',
age: 3
}
}
映射类型—Pick
interface IInfo{
name: string
age: number
}
type PartProp = Pick<IInfo,"name">
let res1: PartProp = {
name: '法外狂徒张三'
}
其他公共类型
其他公共类型—Required
interface IPerson{
name?: string
age?: number
}
let res: IPerson = {
name: '法外狂徒张三'
}
let res1: Required<IPerson> = {
name: '法外狂徒张三',
age: 22
}
其他公共类型—Omit<Type,Keys>
interface Student{
name: string
age: number
score: number
sex: boolean
}
type SProps = Omit<Student,"name">
let res2: SProps = {
age: 18,
score: 99,
sex: true
}
其他公共类型—OmitThisParameter
function add(x: number):void {
console.log(x)
}
function f0(this: object,x: number){}
function f1(x: number){}
type T0 = OmitThisParameter<typeof f0>
type T1 = OmitThisParameter<typeof f1>
type T2 = OmitThisParameter<string>