【问题标题】:How can I use a Record's value as an object key whose interface is the same type如何将记录的值用作接口类型相同的对象键
【发布时间】:2021-04-13 16:37:04
【问题描述】:

我定义了一个字符串的 OR 类型(由于不相关的情况,这不能是枚举)

export type AnimalTypes =
    | 'dog'
    | 'cat'
    | 'donkey'
    | 'elephant';

我使用这个类型作为导出的Record中的值

export const PartyTypes: Record<string, AnimalTypes> = {
    DOG_PARTY: 'dog',
    CAT_PARTY: 'cat',
    DEMOCRAT_PARTY: 'donkey',
    REPUBLICAN_PARTY: 'elephant',
};

在一个单独的文件中,我导入上面的两个,并以AnimalType 为键创建一个接口

interface ElectionState {
    votesByParty: Record<AnimalTypes, PartyVotesCollection>;
}

当我尝试使用 PartyTypes 记录实现此接口的对象字面量时,对象键出现错误

export const initialState: ElectionState = {
    votesByParty: {
        PartyTypes.DOG_PARTY: {
            electionsWon: 0,
            voteCount: 0,
        },
    },
};

Type '{ PartyTypes: Record; ““: 任何; }' 不可分配给类型 'Record'。 对象字面量只能指定已知属性,并且类型 'Record'.ts(2322)

中不存在 'PartyTypes'

如何使用 Record 的值作为从接口继承的另一个对象的键?

Playground

【问题讨论】:

    标签: typescript


    【解决方案1】:

    注意事项:

    export const initialState: ElectionState = {
        votesByParty: {
            PartyTypes.DOG_PARTY: 0,
        },
    };
    

    应该是

    export const initialState: ElectionState = {
        votesByParty: {
            [PartyTypes.DOG_PARTY]: 0,
        },
    };
    

    另外,votesByParty 类型需要所有方(除非您想从中制作部分类型)

    export const initialState: ElectionState = {
        votesByParty: {
            [PartyTypes.DOG_PARTY]: 0,
            [PartyTypes.CAT_PARTY]: 0,
            [PartyTypes.DEMOCRAT_PARTY]: 0,
            [PartyTypes.REPUBLICAN_PARTY]: 0,
        },
    };
    

    这仍然会出错,因为PartyTypes.DOG_PARTY 可以是任何类型的AnimalTypes,所以我们不能保证votesByParty 将拥有所有这些。毕竟,这是:

    export const PartyTypes: Record<string, AnimalTypes> = {
        DOG_PARTY: 'cat',
        CAT_PARTY: 'cat',
        DEMOCRAT_PARTY: 'cat',
        REPUBLICAN_PARTY: 'cat',
    };
    

    仍然有效。

    因为我们需要确保votesByParty拥有所有的当事人,所以我们需要改变:

    export const PartyTypes = {
        DOG_PARTY: 'dog',
        CAT_PARTY: 'cat',
        DEMOCRAT_PARTY: 'donkey',
        REPUBLICAN_PARTY: 'elephant',
    } as const;
    

    除非您想删除对象中包含所有参与方的要求,否则在这种情况下:

    interface ElectionState {
        votesByParty: Partial<Record<AnimalTypes, number>>;
    }
    

    【讨论】:

    • 感谢您的解释,其他任何偶然发现此问题的人:Tl;Dr 版本是用[]包围您的对象键
    猜你喜欢
    • 2019-03-17
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 2021-08-17
    • 2020-10-22
    相关资源
    最近更新 更多