基于函数参数的动态返回类型

时间:2020-06-09 20:33:21

标签: typescript

我对Typescript还是很陌生,我被困住了,我试图了解这是否可行。

我的目标是能够使用名为“ fields”的特定选项属性调用函数“ getRecords”,在该属性中输入要从服务器获取的字段,并且我希望打字稿为我建议使用的字段名输入要返回的对象。

我一直在尝试使用单个字段作为输入,但是我的最终目标是使用带有字段名称的数组。

这是示例代码,我还创建了一个打字稿playground

const getRecords = async (options: { fields: string }): Promise<{ result: { [options.fields]: string}[] } | undefined> => {
    return await new Promise((resolve, reject) => {
        //Fetch Something here
        resolve({
            result: [
                { name: 'Test Name' }
            ]
        })
        reject(undefined)
    })
}

const test = async () => {
    let data = await getRecords({
        fields: 'name'
    })

    console.log(data)
}

test()

我唯一能使用它的是当我在返回的承诺中将密钥硬编码为这样的时候:

Promise<{ result: { ['name']: string}[] } | undefined>

非常感谢您对此提供的帮助

谢谢!

1 个答案:

答案 0 :(得分:1)

像这样的事情会做我认为你要追求的事情:

const makeKeys = <T extends string>(fields: T[]): Record<T, string> => {
    // Sample implementation

    const map: Record<T, string> = {} as Record<T, string>
    for (const field of fields) {
        map[field] = 'test value';
    }

    return map;
}

const obj = makeKeys(['test', 'thing']);

// These fields can now be safely accessed with autocomplete :)
obj.thing // string
obj.test  // string

这里的关键是我们指定将字符串数组传递给函数

<T extends string>(fields: T[])

该函数将返回一个Record type,其键与数组中包含的字符串完全相同

Record<T, string>

一旦TS知道类型系统可以推断出,您传递到输入数组的任何字符串将是输出对象的键。

// These fields can now be safely accessed with autocomplete :)
obj.thing // string
obj.test  // string