繁体   English   中英

Typescript - 类型保护不会缩小与泛型类型和函数的联合

[英]Typescript - type guard not narrowing a union with generic types and functions

我有两个使用以下方法的名义类型的函数(抛开为什么我会这样做 - 这个例子被简化以试图让我的问题清楚):

interface OneArgFunc<T> { 
 label: "oneArgFunc"
 innerFunc:(x: string, y:T)=>void
}
interface TwoArgFunc<T> {
 label: "twoArgFunc"
 innerFunc: (a:number, b:string, c:T)=>void
}

我也有两者的联合和类型守卫来区分:

type UnionFunc<V> = OneArgFunc<V> | TwoArgFunc<V>

// Type guard functions
function isOneArgFunc<V>(func: UnionFunc<V>): func is OneArgFunc<V> {
    return func.label === "oneArgFunc"
}
function isTwoArgFunc<V>(func: UnionFunc<V>): func is TwoArgFunc<V> {
    return func.label === "twoArgFunc"
}

但是如果我调用联合中的一个类型守卫,它不会将余数(“else”语句)缩小到联合的另一半:

function transfomer<U extends UnionFunc<any>>(func:U){
    if(isOneArgFunc(func)) {
       return (g:any)=>func.innerFunc("test", g)
    }
    else {
        return (g:any)=>func.innerFunc(1, "test", g)
        //                             ^ -- error here
        // TS indicates that narrowed type of innerFunc is
        // (property) innerFunc: (arg0: never, arg1: any, c: any) => void
        //  What is that based on?
    }
}

如果我在 else 语句中显式调用第二个类型保护,它会按预期工作:

function transfomerTwo<U extends UnionFunc<any>>(func:U){
    if(isOneArgFunc(func)) {
       return (y:any)=>func.innerFunc("test", y)
    }
    else if(isTwoArgFunc(func)) {
        return (z:any)=>func.innerFunc(1, "test", z)
    }
    else {return func}
}

但我不明白为什么上面的第一个不起作用? 由于某种原因,我假设联合并不是真正的二进制,但我无法确切地看到 TS 如何或如何在 else 语句之后为innerFunc 提供奇怪的函数签名。

任何人都可以帮助我理解这一点吗?

完整代码在这个操场上。

以下对你有用吗? 我认为最好将泛型类型指定为 isOneArgFunc。 至少它不再引发任何错误。

function transfomer<T>(func:UnionFunc<T>){
    if(isOneArgFunc<T>(func)) {
       return (g:any)=>func.innerFunc("test", g)
    }
    else {
        return (g:any)=>func.innerFunc(1, "test", g)
        //                             ^ -- No more error
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM