Typescript获取对象';具有类型安全性的密钥名
如何使用类型安全性从对象或记录获取密钥?Typescript获取对象';具有类型安全性的密钥名,typescript,Typescript,如何使用类型安全性从对象或记录获取密钥? 下面的示例打印dog max,但dog是硬编码字符串。我能以某种方式删除硬编码吗 type pettype = 'dog' | 'cat' const pets: Record<pettype, string> = { 'dog': 'max', 'cat': 'juliet', } // Print "dog max" without hardcoding 'dog' console.log('dog', p
下面的示例打印
dog max
,但dog
是硬编码字符串。我能以某种方式删除硬编码吗
type pettype = 'dog' | 'cat'
const pets: Record<pettype, string> = {
'dog': 'max',
'cat': 'juliet',
}
// Print "dog max" without hardcoding 'dog'
console.log('dog', pets.dog)
// Looking at something like nameof(pets.dog)
type pettype='dog'|'cat'
常数宠物:记录={
“狗”:“max”,
“猫”:“朱丽叶”,
}
//打印“dog max”而不硬编码“dog”
console.log('dog',pets.dog)
//查看类似于(pets.dog)名称的内容
不要执行与nameof('max')相同的nameof(pets.dog)
,
将pettype作为nameof的参数
const-nameof(宠物:宠物类型)=>{
console.log(宠物,宠物[pet])
}
如果您确实想通过名称查找宠物的类型,您应该切换宠物的键和值。如果您不想在以后的代码中使用字符串文字“dog”,并且希望使用类似常量字符串变量的内容,您可以定义const
变量
比如说,
const DOG=“DOG”;
const CAT=“CAT”;
宠物类型=狗的类型|猫的类型;
常数宠物:记录={
[狗]:“max”,
[猫]:“朱丽叶”,
};
console.log(狗,宠物[狗])
请注意,定义联合类型时使用typeof
运算符,变量用作键时使用括号。我不能100%确定这是否是您想要的,但从您的示例中,我假设您想要打印“dog max”
,方法是只传递对象而不传递“dog”
字符串
type PetType = 'dog' | 'cat';
const pets: Record<PetType, string> = {
'dog': 'max',
'cat': 'juliet',
}
function nameof(name: string) {
// find key by value
const [petType] = Object.entries(pets).find(([_petType, petName]) => petName === name) || []
console.log(petType, name);
}
nameof(pets.dog); // dog max
nameof(pets.cat); // cat juliet
nameof("foo"); // undefined foo
type PetType='dog'|'cat';
常数宠物:记录={
“狗”:“max”,
“猫”:“朱丽叶”,
}
函数名称(名称:字符串){
//按值查找键
const[petType]=Object.entries(pets.find)([\u petType,petName])=>petName==name)| |[]
console.log(类型、名称);
}
(宠物、狗)的名字;//狗麦克斯
(宠物猫)的名字;//猫朱丽叶
名称(“foo”);//未定义的foo
但是,如果有同名的宠物,这可能会成为一个问题
如果宠物名是定义的/静态值,则更严格:
// Generic type to get object value as union type
type ValueOf<T> = T[keyof T];
type PetType = 'dog' | 'cat';
type PetName = 'max' | 'juliet';
const pets: Record<PetType, PetName> = {
'dog': 'max',
'cat': 'juliet',
}
function nameof(name: ValueOf<typeof pets>) {
const [petType] = Object.entries(pets).find(([_petType, petName]) => petName === name) || []
console.log(petType, name);
}
nameof(pets.dog); // dog max
nameof(pets.cat); // cat juliet
nameof("foo"); // "foo" is not assignable to parameter of type ValueOf<Record<PetType, PetName>>
//将对象值获取为联合类型的泛型类型
类型值of=T[keyof T];
类型PetType='dog'|'cat';
键入PetName='max'|'juliet';
常数宠物:记录={
“狗”:“max”,
“猫”:“朱丽叶”,
}
函数名称of(名称:ValueOf){
const[petType]=Object.entries(pets.find)([\u petType,petName])=>petName==name)| |[]
console.log(类型、名称);
}
(宠物、狗)的名字;//狗麦克斯
(宠物猫)的名字;//猫朱丽叶
名称(“foo”);//“foo”不可分配给ValueOf类型的参数
或更干净的版本:
// Generic type to get object value as union type
type ValueOf<T> = T[keyof T];
const pets = {
dog: 'max',
cat: 'juliet',
} as const;
// You can also extract the type if needed
type PetKeys = keyof typeof pets; // "dog" | "cat"
type PetNames = ValueOf<typeof pets>; // "max" | "juliet"
function nameof(name: ValueOf<typeof pets> /* or PetNames */) {
const [petType] = Object.entries(pets).find(([_petType, petName]) => petName === name) || []
console.log(petType, name);
}
nameof(pets.dog); // dog max
nameof(pets.cat); // cat juliet
nameof("foo"); // Error because "foo" != "max" or "juliet"
//将对象值获取为联合类型的泛型类型
类型值of=T[keyof T];
常数宠物={
狗:“max”,
猫:“朱丽叶”,
}作为常量;
//如果需要,还可以提取类型
类型PetKeys=类型pets的keyof;//“狗”|“猫”
键入PetNames=ValueOf;//“马克斯”|“朱丽叶”
函数名称of(名称:ValueOf/*或PetNames*/){
const[petType]=Object.entries(pets.find)([\u petType,petName])=>petName==name)| |[]
console.log(类型、名称);
}
(宠物、狗)的名字;//狗麦克斯
(宠物猫)的名字;//猫朱丽叶
名称(“foo”);//错误,因为“foo”!=“马克斯”或“朱丽叶”
不太清楚您所说的“狗钥匙类型安全”是什么意思<代码>宠物。狗
是类型安全的-您的记录类型已确定,狗
是宠物
上的一个键。如果您的意思是pets.dog
的值应该是类型安全的(即始终等于'max'
,而不是string
),那么您需要一个与pets
完全匹配的界面,而不是一条记录。在console.log中,我有字符串dog
。我不想硬编码。如果将来我想将该属性重命名为其他属性,我需要编译时安全性。它已经是类型安全的。例如,如果键入Dog
而不是Dog
,则会出现编译错误,因为Dog
不在类型pettype
中。