【问题标题】:Typescript Interface objects property value as key打字稿接口对象属性值作为键
【发布时间】:2018-07-14 01:39:34
【问题描述】:

当尝试将对象数组映射到具有相同对象但使用属性值作为索引键的数组时,我尝试为情况创建正确的类型。

Code on playground

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;
}

谢谢。

【问题讨论】:

  • 这些名称在编译时是否已知?
  • 是的,众所周知。

标签: typescript generics typescript-typings


【解决方案1】:

您应该在name 属性的字符串文字类型中使您的ValueDefinition 接口通用,以便稍后提取它:

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&lt;'super'&gt;ValueDefinition&lt;'thing'&gt;

const objKey = getByName([obj, obj2]);  

objKey 被键入为ValueDefinitionObject&lt;'super'|'thing'&gt;。让我们使用它:

objKey.super; // okay, ValueDefinition<'super'>
objKey.thing; // okay, ValueDefinition<'thing'>
objKey.nope; // error, property 'nope' doesn't exist

这对你有用吗?祝你好运!

【讨论】:

  • 你打败了我 :)
  • @TitianCernicova-Dragomir 哦,对不起!
  • 没关系,公平公正:)
猜你喜欢
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 2019-10-03
  • 2017-06-29
  • 2021-07-24
  • 2019-02-10
  • 2018-08-21
  • 1970-01-01
相关资源
最近更新 更多