一些补充
unknown类型
- unknown 类型代表任何值。这与 any 类型类似,但更安全,因为对未知 unknown 值做任何事情都是不合法的。
- unknown 类型被称作安全的any
// unknown 类型代表任何值。这与 any 类型类似,但更安全,因为对未知 unknown 值做任何事情都是不合法的。
// unknown 类型被称作安全的any
// 1.任何类型都可以赋值给unknown类型
let str:unknown;
str = 18;
str = "张馨予";
str = false;
// 2.不能将unknown类型赋值给其它类型
let val:unknown = 18;
let num: number;
// num = val; // 报错
// 使用类型断言
num = val as number;
// 使用类型缩小
if(typeof val == "number") {
num = val;
}
// 3.unknown与其它任何类型组成的交叉类型最后都是其它类型
type MyType1 = number & unknown;
type MyType2 = unknown & boolean;
let a:MyType1 = 18;
let b:MyType2 = true;
// 4.unknown除了与any以外, 与其它任何类型组成的联合类型最后都是unknown类型
type MyType3 = unknown | any;
type MyType4 = unknown | number;
type MyType5 = unknown | string | boolean;
// 5.never类型是unknown类型的子类型
type MyType6 = never extends unknown ? true : false;
map类型
Map 对象保存键值对,并且能够记住键的原始插入顺序。
任何值(对象或者原始值) 都可以作为一个键或一个值。
Map 是 ES6 中引入的一种新的数据结构
可以使用for of 进行迭代
创建map:
let myMap = new Map();
Map 相关的函数与属性:
- map.clear() – 移除 Map 对象的所有键/值对 。
- map.set() – 设置键值对,返回该 Map 对象。
- map.get() – 返回键对应的值,如果不存在,则返回 undefined。
- map.has() – 返回一个布尔值,用于判断 Map 中是否包含键对应的值。
- map.delete() – 删除 Map 中的元素,删除成功返回 true,失败返回 false。
- map.size – 返回 Map 对象键/值对的数量。
- map.keys() - 返回一个 Iterator 对象, 包含了 Map 对象中每个元素的键 。
- map.values() – 返回一个新的Iterator对象,包含了Map对象中每个元素的值 。
let nameSiteMapping = new Map();
// 设置 Map 对象
nameSiteMapping.set("邱淑贞", 1);
nameSiteMapping.set("宋茜", 2);
nameSiteMapping.set("景甜", 3);
// 获取键对应的值
console.log(nameSiteMapping.get("Runoob")); // 2
// 判断 Map 中是否包含键对应的值
console.log(nameSiteMapping.has("Taobao")); // true
console.log(nameSiteMapping.has("Zhihu")); // false
// 返回 Map 对象键/值对的数量
console.log(nameSiteMapping.size); // 3
// 删除 Runoob
console.log(nameSiteMapping.delete("Runoob")); // true
console.log(nameSiteMapping);
// 移除 Map 对象的所有键/值对
nameSiteMapping.clear(); // 清除 Map
console.log(nameSiteMapping);
// 迭代 Map 中的 key
for (let key of nameSiteMapping.keys()) {
console.log(key);
}
// 迭代 Map 中的 value
for (let value of nameSiteMapping.values()) {
console.log(value);
}
// 迭代 Map 中的 key => value
for (let entry of nameSiteMapping.entries()) {
console.log(entry[0], entry[1]);
}
// 使用对象解析
for (let [key, value] of nameSiteMapping) {
console.log(key, value);
}
索引类型
- 我们可以使用一个索引访问类型来查询另一个类型上的特定属性
- 格式: [ key]
- 注意点: 不会返回null/undefined/never类型
// 我们可以使用一个索引访问类型来查询另一个类型上的特定属性
// 格式: []
class Person {
name: string
age: number
}
type MyIndex = Person["name"];
let a:MyIndex = "赵韩樱子";
console.log(a);
// 获取指定对象, 部分属性的值, 放到数组中返回
let obj = {
name:'吴倩',
age:18,
gender: 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']);
console.log(res);
// 不会返回null/undefined/never类型
interface TestInterface {
a:string,
b:number,
c:boolean,
d:symbol,
e:null,
f:undefined,
g:never
}
type MyType = TestInterface[keyof TestInterface];
条件类型
- 条件类型的形式看起来有点像JavaScript中的条件表达式:
T extends U ? TrueType : FalseType - 应用场景: 解决函数重载问题
// 1.条件类型
// 条件类型的形式看起来有点像JavaScript中的条件表达式
// T extends U ? TrueType : FalseType
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 ""
// }
// 条件类型
type MyType<T> = T extends string ?: string : any
type res = MyType<string>
// 2.应用场景:解决函数重载问题
type Condition<T> = T extends string ? IName : IAge
function reLoad<T extends number | string>(idOrName: T): Condition<T> {
throw ""
}
let res1 = reLoad("王丽坤")
let res2 = reLoad(100)
分布式条件类型
- 当条件类型作用于一个通用类型时,当给定一个联合类型时,它们就变成了分布式的
- 通常情况下,分布性是需要的行为。为了避免这种行为,你可以用方括号包围 extends 关键字的每一 边。
// 定义:被检测类型是一个联合类型的时候, 该条件类型就被称之为分布式条件类型
// type MyType<T> = T extends any ? T : never;
// type res = MyType<string | number | boolean>;
// 从T中剔除可以赋值给U的类型。 Exclude
// type res = Exclude<string | number | boolean, number>
// 提取T中可以赋值给U的类型。 Extract
// type res = Extract<string | number | boolean, number>
// 从T中剔除null和undefined。 NonNullable
// type res = NonNullable<string | boolean | null | undefined>
// 获取函数返回值类型。 ReturnType
// type res = ReturnType<()=>number>
// 获取一个类的构造函数参数组成的元组类型。 ConstructorParameters
// class Person {
// constructor(name:string, age:number){}
// }
// type res = ConstructorParameters<typeof Person>;
// 获得函数的参数类型组成的元组类型。 Parameters
// function say(name:string, age:number, gender:boolean) {
// }
// type res = Parameters<typeof say>;
infer关键字推断
- 条件类型为我们提供了一种方法来推断我们在真实分支中使用 infer 关键字进行对比的类型
- 我们可以使用 infer 关键字编写一些有用的辅助类型别名
// 假如想获取数组里的元素类型,如果是数组则返回数组中元素的类型,否则返回这个类型本身
type Id = number[];
type IName = string[];
type Unpacked<T> = T extends IName ? string : T extends Id ? number : T;
type idType = Unpacked<Id>; // idType 类型为 number
type nameType = Unpacked<IName>; // nameType 类型为string
// 使用infer简化操作
type ElementOf<T> = T extends Array<infer E> ? E : T;
type res1 = ElementOf<string[]>; // string
type res2 = ElementOf<boolean>; // boolean
// infer可以推断出联合类型
type Foo<T> = T extends { a: infer U; b: infer U } ? U : never;
type T11 = Foo<{ a: string; b: number }>; // T11类型为 string | number