如何将打字稿泛型限制为两个基元之一?

Nia*_*all 8 typescript typescript-generics

我正在编写一个函数,该函数通过参数列表来查找元素。如果找到,该函数将删除名称并返回值,如果不存在,则返回默认值。这些值将为 anumberstring。我想要一种使用打字稿泛型的方法,以及编译以下内容的约束。

function GetValue<T extends number | string>(datum: string, element: string, defaultValue: T): T {
    if (datum.startsWith(element)) {
        if (typeof defaultValue === 'number')
            return parseInt(datum.substring(element.length)); // error
        else if (typeof defaultValue === 'string')
            return datum.substring(element.length); // error
    }
    return defaultValue;
}
Run Code Online (Sandbox Code Playgroud)

我已经排除了任何错误检查代码,例如从parseInt. 这将被称为;

console.log(GetValue("abc123", "abc", 456));
console.log(GetValue("abc123", "def", 456));
Run Code Online (Sandbox Code Playgroud)

并期望123出去456

目前,它失败了,因为可以使用扩展 a or但不是 a or 的// error类型来调用该函数。stringnumberstringnumber

如何限制泛型,T使其仅限于 a stringor number(而不是 union string | number),然后返回类型与 the 的类型匹配defaultValue

Mar*_*ina 9

将显式转​​换为 T,以消除此错误

function GetValue<T extends number | string>(datum: string, element: string, defaultValue: T): T {
    if (datum.startsWith(element)) {
        if (typeof defaultValue === 'number')
            return parseInt(datum.substring(element.length)) as T;
        else if (typeof defaultValue === 'string')
            return datum.substring(element.length) as T;
    }
    return defaultValue;
}
Run Code Online (Sandbox Code Playgroud)

github 上有一个开放的问题讨论了这个主题。