做房产抵押网站需要什么手续,wordpress有访客记录,如何利用某个软件做一个网站,财税公司怎么找客源概述
Record 类型是TS中其众多强大特性之一它为我们提供了创建键值对映射的强大能力极大地增强了代码的灵活性与类型安全性
应用示例 1 #xff09;用于配置场景
在复杂的项目中#xff0c;配置文件往往包含多个模块的不同设置使用 Record 可以确保配置的键名正确且值类型…概述
Record 类型是TS中其众多强大特性之一它为我们提供了创建键值对映射的强大能力极大地增强了代码的灵活性与类型安全性
应用示例 1 用于配置场景
在复杂的项目中配置文件往往包含多个模块的不同设置使用 Record 可以确保配置的键名正确且值类型统一
示例
interface AppConfig {port: number;env: development | production;
}const config: Recordstring, AppConfig {server: { port: 3000, env: development },client: { port: 8080, env: production },
};2 枚举场景
Record 也常用于将枚举类型转换为易于使用的键值对映射便于在代码中引用
示例
enum Color {Red,Green,Blue,
}const colorNameMap: RecordColor, string {[Color.Red]: Red,[Color.Green]: Green,[Color.Blue]: Blue,
};3 联合类型场景
示例
type Scores RecordMath | English | Science, number; const studentScores: Scores { Math: 90, English: 85, Science: 92
};4 表单项的配置
在构建动态表单时Record 可以用来定义表单项的配置每个表单项都有其特有的属性
示例
interface FormField {type: text | checkbox | select;label: string;required?: boolean;
}const formConfig: Recordstring, FormField {username: { type: text, label: Username, required: true },agreeTerms: { type: checkbox, label: Agree to terms, required: false },
};5 ) 映射类型类似Record
type InvertT { [P in keyof T as T[P] extends string ? T[P] : never]: P;
}; type Original { a: 1; b: 2 };
type Inverted InvertOriginal; // 测试反转类型
const invertedObj: Inverted { 1: a, 2: b
}; // 这是一个类型守卫函数用于在运行时检查对象是否符合 Inverted 类型
function isInvertedType(obj: any): obj is Inverted { return 1 in obj 2 in obj obj[1] a obj[2] b;
} if (isInvertedType(invertedObj)) { console.log(invertedObj 符合 Inverted 类型);
} else { console.log(invertedObj 不符合 Inverted 类型);
}InvertT 类型别名通过条件映射使用了as关键字的映射类型语法这在TypeScript 4.1及以后版本中可用来生成一个新的类型该类型实质上是原类型T中每个键值对的倒置但这种方式更加灵活因为它基于值的类型来进行映射在这个例子中要求原对象的值必须是字符串从而可以用作新类型的键因此虽然Inverted类型在功能上类似于某种Record类型的应用但它更准确地描述为一个经过类型系统转换处理后得到的、具有特定键值对的对象类型而不是直接等同于使用Record定义的类型
6 自定义Record(硬编码联合类型映射)
示例
// 1. 使用 TypeScript 内置的 Record 类型
type UserRecord Recordstring, any; // 允许任何字符串作为键任何类型作为值 // 假设我们有一个具体的键集合和值类型
type SpecificKeys username | age;
type SpecificUserRecord RecordSpecificKeys, string; // 键必须是 username 或 age值必须是 string // 2. 自定义一个类似 Record 的类型但键是硬编码的这不是一个好的做法因为它不够灵活
type MyRecordT { [P in username | age]: T; // 硬编码的键 username 和 age值类型由泛型 T 指定
};// 使用自定义的 MyRecord 类型
type MyUserRecord MyRecordstring; // 键是 username 或 age值都是 string // 示例对象
const user: SpecificUserRecord { username: Alice, age: 30 // 注意这里为了演示使用了字符串但在实际应用中年龄应该是数字
}; const myUser: MyUserRecord { username: Bob, age: 25 // 同样这里使用了字符串作为示例
}; // 说明
// 1. 内置的 Record 类型更加灵活允许您指定任何键的集合K extends keyof any和值的类型T。
// 2. 自定义的 MyRecord 类型在这里是硬编码的它只允许 username 和 age 作为键并且值的类型由泛型 T 指定。
// 3. 在实际应用中通常推荐使用内置的 Record 类型因为它更加灵活且易于维护。7 ) 类型谓词与模式匹配
示例
function isRecordOfStrings(obj: any): obj is Recordstring, string {return typeof obj object obj ! null Object.values(obj).every(v typeof v string);
}if (isRecordOfStrings(someObj)) {// 在此块内someObj 被认为是 Recordstring, string
}通过类型谓词和 Record 结合可以实现更加精准的类型判断和模式匹配逻辑
8 ) Record 与 索引签名
示例
// 假设我们有一个Goods类型
type Goods { id: number; name: string;
}; // TypeScript内置的Record类型
type RecordTypeK extends keyof any, T { [P in K]: T;
}; // 使用Record类型来创建一个新的类型该类型的属性与Goods的键相同但值都是string类型
type resultGoodsType RecordTypekeyof Goods, string;
// 这等价于
// type resultGoodsType {
// id: string;
// name: string;
// }; // 类似索引签名的类型定义但不是Record
type IndexSignatureType { [x: string]: any; // 字符串索引签名允许任何字符串作为键值是any类型 // 注意一旦你定义了字符串索引签名那么就不能再为特定的属性名定义更具体的类型了 // 因为所有属性名最终都会被视为字符串并遵循这个索引签名的类型
}; // 索引签名不能包含number或symbol作为键类型除了特殊的数组和Map类型
// type BadIndexSignatureType {
// [x: number]: any; // 错误索引签名参数类型必须为 string 或 number 或 symbol。
// }; // 使用Record和索引签名的区别
// Record类型允许你明确指定键的类型和值的类型
// 而索引签名则提供了一种更通用的方式来描述对象的结构但会限制你对特定键的类型定义 // 示例使用Record和索引签名
const recordExample: resultGoodsType { id: 123, // 符合resultGoodsType的定义因为id现在是string类型 name: Apple // 符合resultGoodsType的定义因为name现在是string类型
}; const indexSignatureExample: IndexSignatureType { id: 123, // 符合IndexSignatureType的定义因为id被视为字符串键但其值可以是any类型 name: Banana, // 符合IndexSignatureType的定义 some-other-key: true // 也符合因为所有字符串键都符合索引签名的定义
};联系
Record类型和索引签名都用于描述对象的结构它们都允许你使用类型参数来定义键和值的类型
区别
Record是一个内置工具类型它接受两个类型参数来明确指定键和值的类型索引签名是TypeScript中对象类型定义的一部分它允许你定义一个或多个类型的键通常是string或number并为这些键指定一个值的类型一旦你定义了一个字符串索引签名那么你就不能再为对象的特定属性定义更具体的类型了除非该类型与索引签名的类型兼容这是因为所有属性名最终都会被视为字符串并遵循这个索引签名的类型。Record类型提供了一种更精确和可控的方式来定义对象的结构而索引签名则提供了一种更通用和灵活的方式来描述对象的结构
9 实现轻量级 Map
type SimpleMapKeyType extends string | number | symbol, ValueType {[key in KeyType]: ValueType;
};class LightMapKeyType extends string | number | symbol, ValueType {private map: SimpleMapKeyType, ValueType;constructor() {this.map {} as SimpleMapKeyType, ValueType;}set(key: KeyType, value: ValueType): void {this.map[key] value;}get(key: KeyType): ValueType | undefined {return this.map[key];}delete(key: KeyType): boolean {const hasKey key in this.map;if (hasKey) {delete this.map[key];}return hasKey;}has(key: KeyType): boolean {return key in this.map;}
}const myMap new LightMapstring, number();myMap.set(apple, 1);
myMap.set(banana, 2);console.log(myMap.get(apple)); // 输出1
console.log(myMap.has(cherry)); // 输出false
console.log(myMap.delete(banana)); // 输出true
console.log(myMap.has(banana)); // 输出falseRecord是TypeScript的一个内置类型别名它允许你基于一个索引类型键和一个值类型创建一个对象类型例如Recordstring, number定义了一个所有键为字符串、值为数字的对象类型我们的轻量级Map实现将包括以下几个基本操作 设置值 set(key, value)获取值get(key)删除值delete(key)检查找键是否存在has(key) 泛型SimpleMap允许键为string、number或symbol值为任意类型ValueType通过TypeScript的Record类型和类我们实现了一个轻量级的Map数据结构它在编译时提供类型安全检查确保了键值的类型正确性虽然它不具备JavaScript内置Map对象的所有功能如迭代器、容量自动扩展等但足以应对一些简单场景且在类型安全方面提供了额外保障