如何缩小函数中参数的类型?

问题描述 投票:0回答:1

我有类型狭窄的问题。如何缩小参数 v 的类型以成功将其传递给 funcAorB?

// type.d.ts
export type A = "A1" | "A2";
export type B = "B1" | "B2";
export type U = A | B;

export function funcAorB(v: A) : A;
export function funcAorB(v: B) : B;

// test.ts
function wrappFunAorB<T extends U>(v:T) {
  type V<K> = K extends A ? A : B; 
  funcAorB(v as V<T>) // error
}


我预计

V<T>
会缩小T的类型但没有

typescript union type-inference
1个回答
0
投票

由于您已经使用

overloads
定义了 funcAorB,因此 TypeScript 需要知道要调用哪个特定的重载(即使无论哪种方式,它最终都会调用相同的实现函数)。也就是说,它必须知道 runtime
v
A
还是
B
。编译时检查将不起作用。

你至少有两个选择:

  1. 实现一个类型谓词来缩小

    v
    ,例如:

    function isA(value: any): value is A {
        return value === "A1" || value === "A2"; // Just an example, you probably want something more robust, where the check and the type have the same single source
    }
    

    ...然后使用逻辑让 TypeScript 看到一个缩小的类型,例如:

    function wrappFunAorB<T extends U>(v :T) {
        if (isA(v)) {
            funcAorB(v);
        } else {
            funcAorB(v);
        }
    }
    

    游乐场链接

  2. 实现接受联合类型的函数,而不是使用重载。它可以直接接受联合:

    function funcAorB(v: A | B): A | B {
        // ...
    }
    

    游乐场链接

    或者它可以使用泛型类型参数:

    function funcAorB<T extends A | B>(v: T): T {
        // ...
    }
    

    游乐场链接

© www.soinside.com 2019 - 2024. All rights reserved.