我想检查传递的类型是否正确。请参见下面的代码示例。但我不知道如何根据返回类型进行检查,因为FunctionA
和FunctionB
的参数相同。
type TypeA = { a: string };
type TypeB = { a?: string, b: Record<string, any> };
type FunctionA = ( argA: string ) => TypeA | Promise<TypeA>;
type FunctionB = ( argA: string ) => TypeB | Promise<TypeB>;
function isFunctionB(target: FunctionA | FunctionB): target is FunctionB {
return true //How do I check the type without running the function
}
class Test {
myFunction?: FunctionA | FunctionB;
mustBeFunctionB: boolean;
constructor({
myFunction,
mustBeFunctionB
}: {
myFunction?: FunctionA | FunctionB;
mustBeFunctionB: boolean;
}) {
this.myFunction = myFunction;
this.mustBeFunctionB = mustBeFunctionB
if (mustBeFunctionB && myFunction && !isFunctionB(myFunction)) {
throw new Error(
"Invalid constructor arguments! myFunction must be a type of FunctionB"
);
} else {
console.log("Passed")
}
}
}
async function myFunctionA(argA: string): Promise<{ a: string }> {
return { a: "test" };
}
const test = new Test({
myFunction: myFunctionA,
mustBeFunctionB: true
}); // This should fail but it still passed
2条答案
按热度按时间kxkpmulp1#
如果不执行函数,就无法在运行时检查函数是否符合给定的签名(包括返回类型),因为那时类型信息不存在。
我能想到的解决这个问题的唯一方法是使用品牌类型,如下所示:
这将允许您在运行时区分这两种类型,前提是它们定义正确。
如果您打算更频繁地重用这种模式,您可能需要查看
ts-brand
。hgncfbus2#
解决方案1:方法重载
你可以利用方法重载来实现它。下面是一个简化的代码示例来展示这个概念。
它也可以用于类构造函数。请参见playground中对代码的修改
解决方案2:并集类型参数
如果您可以像代码中那样使用单个对象配置,也可以使用union声明输入,以指定
mustBeFunctionB
标志的对等项。运动场
要注意,这些解决方案并不检查运行时的确切上下文,而只是像你在标题中所说的“类型守卫”,然而,typescript会防止你做出错误的输入,这就是typescript的概念。