如何从类型安全的对象或记录中获取密钥?
下面的示例打印 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)
答案 0 :(得分:0)
而不是执行与 nameof(pets.dog)
相同的 nameof('max')
将 pettype 作为 nameof
的参数
const nameof(pet: pettype) => {
console.log(pet, pets[pet])
}
如果您确实想通过名称查找宠物的类型,则应该切换宠物的键和值。
答案 1 :(得分:0)
如果您不想在后面的代码中使用字符串字面量“dog”并且想使用诸如常量字符串变量之类的东西,您可以定义 const
变量。
例如
const DOG = "dog";
const CAT = "cat";
type pettype = typeof DOG | typeof CAT;
const pets: Record<pettype, string> = {
[DOG]: 'max',
[CAT]: 'juliet',
};
console.log(DOG, pets[DOG])
注意typeof
运算符在定义联合类型时使用,括号在变量作为键时使用。
答案 2 :(得分:0)
我不能 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
但是,如果有同名的宠物,这可能会成为一个问题
或者更严格,如果宠物名称是定义的/静态值:
// 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>>
或更干净的版本:
// 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"