我有类型狭窄的问题。如何缩小参数 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的类型但没有
由于您已经使用
overloads定义了
funcAorB
,因此 TypeScript 需要知道要调用哪个特定的重载(即使无论哪种方式,它最终都会调用相同的实现函数)。也就是说,它必须知道 runtime v
是 A
还是 B
。编译时检查将不起作用。
你至少有两个选择:
实现一个类型谓词来缩小
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);
}
}
实现接受联合类型的函数,而不是使用重载。它可以直接接受联合:
function funcAorB(v: A | B): A | B {
// ...
}
或者它可以使用泛型类型参数:
function funcAorB<T extends A | B>(v: T): T {
// ...
}