【问题标题】:Typescript: add typing for response object containing both index signature and key-pairsTypescript:为包含索引签名和密钥对的响应对象添加类型
【发布时间】:2019-06-25 15:55:42
【问题描述】:

我不确定为我从后端服务接收的响应对象添加打字稿类型的最佳方法:

{
    de49e137f2423457985ec6794536cd3c: {
        productId: 'de49e137f2423457985ec6794536cd3c',
        title: 'item 1',
    },
    d6623c1a2b843840b14c32685c212395: {
        productId: 'd6623c1a2b843840b14c32685c212395',
        title: 'item 2',
    },
    ids: [
        'de49e137f2423457985ec6794536cd3c',
        'd6623c1a2b843840b14c32685c212395',
    ],
}

它包含一个项目 id 数组 string[] 以及索引签名 [id: string]: Item

Typescript 似乎不喜欢在单个界面中拥有索引签名和数组。例如:

interface ItemList {
    [id: string]: Item;
    ids: string[];
}

我知道在使用索引签名时,其他属性需要返回相同的类型。我是 Typescript 的新手,我有点不确定如何在不将 ids 移出项目对象的情况下使用这些数据?

interface ItemList {
    [id: string]: Item;
    ids: string[];
}
interface Item {
    productId: string;
    title: string;
}

const item: ItemList = {
    de49e137f2423457985ec6794536cd3c: {
        productId: 'de49e137f2423457985ec6794536cd3c',
        title: 'item 1',
    },
    d6623c1a2b843840b14c32685c212395: {
        productId: 'd6623c1a2b843840b14c32685c212395',
        title: 'item 2',
    },
    ids: [
        'de49e137f2423457985ec6794536cd3c',
        'd6623c1a2b843840b14c32685c212395',
    ],
};
console.log(item.ids.map((id: string) => item[id]));

错误

类型“项目”上不存在属性“地图”|字符串[]'。

“项目”类型上不存在属性“地图”。

【问题讨论】:

    标签: typescript object types key-pair index-signature


    【解决方案1】:

    这里的简单解决方法是使用交叉类型:

    type ItemList = {
        [id: string]: Item;
    } & {
        ids: string[];
    }
    interface Item {
        productId: string;
        title: string;
    }
    
    const item: ItemList = Object.assign({ // Can't build the object directly 
        de49e137f2423457985ec6794536cd3c: {
            productId: 'de49e137f2423457985ec6794536cd3c',
            title: 'item 1',
        },
        d6623c1a2b843840b14c32685c212395: {
            productId: 'd6623c1a2b843840b14c32685c212395',
            title: 'item 2',
        }
    }, {
        ids: [
            'de49e137f2423457985ec6794536cd3c',
            'd6623c1a2b843840b14c32685c212395',
        ],
    });
    console.log(item.ids.map((id: string) => item[id]));
    

    交集类型允许不一致的命名属性-索引组合。 (请注意,这不是严格类型安全的,因为 item['ids'] 不会按预期返回 Item,但对于这种情况,这似乎是一个不错的权衡)

    【讨论】:

    • Titian,感谢您的快速回复,这对我来说很有效。您能否解释一下使用 Object.assign 背后的逻辑?使用交集时,这两种对象类型是否需要源自与相交类型匹配的单独对象?没有它,我会收到错误消息:无法分配给类型“ids & items”。
    猜你喜欢
    • 2017-08-02
    • 2016-01-25
    • 1970-01-01
    • 2019-12-22
    • 2016-04-07
    • 2022-06-28
    • 2022-08-23
    • 2017-06-11
    • 1970-01-01
    相关资源
    最近更新 更多