当我尝试使用相同的对象将对象数组映射到数组但使用属性值作为索引键时,我尝试为情境创建正确的输入法。
interface ValueDefinition {
name: string;
}
function getByName<V extends ValueDefinition>(valuDefinitions: V[]) {
let out = {}
for (const key in valuDefinitions) {
out[valuDefinitions[key].name] = valuDefinitions[key];
}
return out;
}
const obj: ValueDefinition = {
name: 'super'
};
const objKey = getByName([
obj
]);
key.super; // Typings for this output
我正在寻找类似的东西:
type WithKey<D extends ValueDefinition> = {
[key: D['name']]: D;
}
感谢。
答案 0 :(得分:2)
您应该在ValueDefinition
属性的字符串文字类型中使name
接口通用,以便稍后提取它:
interface ValueDefinition<K extends string = string> {
name: K
}
然后,您可以将getByName()
函数的输出表示为以下映射类型:
type ValueDefinitionObject<K extends string> = {[P in K]: ValueDefinition<P>}
并修改getByName
的签名在name
文字集合中是通用的:
function getByName<K extends string>(valuDefinitions: Array<ValueDefinition<K>>): ValueDefinitionObject<K> {
let out = {} as ValueDefinitionObject<K>
for (const key in valuDefinitions) {
out[valuDefinitions[key].name] = valuDefinitions[key];
}
return out;
}
此时它会起作用,但您必须小心声明obj
,以便将值'super'
的类型推断为'super'
而不是string
}。这个身份功能将有所帮助:
function asValueDefinition<K extends string>(vd: ValueDefinition<K>): ValueDefinition<K> {
return vd;
}
好的,让我们尝试一下(我正在添加的另一个):
const obj = asValueDefinition({ name: 'super' });
const obj2 = asValueDefinition({ name: 'thing' });
如果您检查它们,则会显示为ValueDefinition<'super'>
和ValueDefinition<'thing'>
。
const objKey = getByName([obj, obj2]);
objKey
的输入为ValueDefinitionObject<'super'|'thing'>
。让我们用它:
objKey.super; // okay, ValueDefinition<'super'>
objKey.thing; // okay, ValueDefinition<'thing'>
objKey.nope; // error, property 'nope' doesn't exist
这对你有用吗?祝你好运!