首页 > 解决方案 > 当我只知道该对象键的模式时如何定义类型?

问题描述

'mykey-0'我有一个函数需要一个带有, 'myotherkey-0', 'mykey-1','myotherkey-1'等键的对象。

问题是我不知道这两个键中是否会有任何一个,我不知道数字是多少(它增加了)

如何为这些可选键表示 TS 类型?类似的东西{ 'mykey-*'?: string, 'myotherkey-*'?: string, otherprop: string }

标签: typescript

解决方案


好的,这不是您直接问题的答案,因为您的数据结构是错误的。事实上,每个键的末尾都有迭代器,这意味着它可能应该是一个数组。考虑我将如何建模:

type MyData = {
  mykey: string,
  myotherkey: string
}
type ArrMyData = MyData[]

function f(arr: ArrMyData) {
    return arr.map(el => el.mykey) // example transformation
}

这种结构还可以选择解决您的问题,因为只有元素不会在数组中。完毕。

总之 - 让我们尝试使用正确的数据结构而不是发明轮子。我写了更多关于我们应该如何考虑状态建模的信息,考虑阅读也许会有所帮助 -状态建模是你的责任


如果这种数据是服务器强制的,我们需要对其进行转换,而不是传播无效结构并进行处理。这种流行的模式是Decoder,顺便说一句 - 这是在 Elm 架构中处理服务器端数据的唯一原因。这样的解码器将被键入为WrongDataStructure -> CorrectDataStructure. 所以让我们编写这样的解码器:

type ApiResponse = Record<string, string>

type WantedData = {
  mykey: string,
  myotherkey: string
}
type ArrMyData = WantedData[]

function decoder(data: ApiResponse): ArrMyData {
    const keys = Object.keys(data);
    return keys.reduce((acc, key) => {
        let i: string | number = key.match(/-([0-9])$/)?.[1] ?? '0';
        i = parseInt(i)
        const cleanKey = key.replace(/-([0-9])$/, '') // remove the index
        if (!acc[i]) {
            acc.push({[cleanKey]: data[key]} as WantedData)
        } else {
            acc[i] = {...acc[i], [cleanKey]: data[key]}
        }
        return acc;
    } ,[] as ArrMyData)
}

const response = { 'mykey-0': 'a', 'myotherkey-0': 'b', 'mykey-1': 'c', 'myotherkey-1': 'd' };
const data = decoder(response);

操场

当我们采用结构并使其更平易近人时,我们正在做的有点像一扇门。我的实现只是示例。


推荐阅读