如果参数是数组,则返回值的数组,否则返回值

时间:2019-06-24 11:29:10

标签: typescript typescript-typings

我想允许AsyncStorage.getAllKeys() .then(keys => AsyncStorage.multiRemove(keys)) .then(() => alert('All Keys removed')); string的数组作为参数。根据要传递的是string还是string的数组,我想返回一个值或一个值数组。

string

如何为此编写适当的类型?

1 个答案:

答案 0 :(得分:2)

我认为我会使用overloads(但可以使用条件类型 ,请参见下文)。在此示例中,我将number用于returnType,但当然仅用于示例:

function example(input: string): number;
function example(input: string[]): number[];
function example(input: string | string[]): number | number[] {
    if (Array.isArray(input)) {
        return (<string[]>input).map(str => Number(str));
    }
    return Number(<string>input);
}

const result1 = example("42");         // `result1`'s type is `number`
const result2 = example(["42", "67"]); // `result2`'s type is `number[]`

on the playground

请注意,其中的第三个只是实施签名example唯一有效的呼叫签名是前两个。


请您发表评论,询问条件类型是否可行,我在现场ping Titian Cernicova-Dragomir,他是TypeScript的SO专家之一。他说他已经看到了问题,并在看到我有:-)时将要发布重载答案,并且他也将为此使用重载-但条件类型可能是 如果您想这样做,则可以打开第三个呼叫签名。这是他想出的:

function example<T extends string | string[]>(input: T): T extends string ? number : number[];
function example(input: string | string[]): number | number[] {
    if (Array.isArray(input)) {
        return (<string[]>input).map(str => Number(str));
    }
    return Number(<string>input);
}

const result1 = example("42");         // `result1`'s type is `number`
const result2 = example(["42", "67"]); // `result2`'s type is `number[]`

on the playground

请注意,引入T可以使我们在参数类型和返回值的(条件)类型中同时使用它。 (这是我错过的尝试将条件类型应用于此的关键部分。)

他指出,条件类型版本打开了第三种调用方式:使用类型为string | string[]的参数,而不是其中一个:

declare const value: string | string[];
let result3 = example(value) // `result3`'s type is `number | number[]`. Would not have worked with overloads.

on the playground

因此,如果您想要第三个呼叫签名,则可以使用条件类型来获取它。否则,重载仅提供前两个签名。