测试表达式是否未通过类型检查



我正在用TypeScript编写一个库,我想检查我的类型定义是否正确。通常,我想检查变量是否具有某种静态类型。我通常这样做:

let expectedToBeString : string = Api.callFunction("param1", 2, []);

但有时,一个类型可能会在我不知情的情况下扩大到any,所以上面的表达式仍然可以编译。因此,我想通过编写一个故意使类型检查失败的表达式来确保它不会any

有时我还想检查我的重载集是否适用于合法类型,但不适用于非法类型,但确保这一点的唯一方法是引发编译错误。

如何验证编译错误是否在应该引发时引发?

有趣的问题。 当条件类型在TypeScript v2.8中发布时,据说本月某个时候(2018年3月)发布,或者现在可以在typescript@next上提供,您将能够执行以下操作:

type ReplaceAny<T, R> = 0 extends (1 & T) ? R : T

除非Tany,否则ReplaceAny<T, R>类型将被T,在这种情况下,它将R。 没有正常的T型应该满足0 extends (1 & T),因为1 & T至少应该和1一样窄,而且0不是1的亚型。 但是 TypeScript 中的any类型打破了规则:它被认为是所有其他类型的超类型和子类型(或多或少)。 这意味着1 & any变得any0 extends any是真的。 所以0 extends (1 & T)的行为就像一个any探测器。

现在我们可以做一个这样的便利函数:

const replaceAny = <R>() => <T>(x: T): ReplaceAny<T,R> => x as any;

如果你调用replaceAny<{}>(),它会生成一个函数,该函数将接受任何输入并返回一个类型{}的值,如果该输入是any类型。

因此,让我们检查一些场景:

declare const Api: {
callFunctionS(...args: any[]): string,
callFunctionN(...args: any[]): number,
callFunctionA(...args: any[]): any,
}
let expectedToBeString: string;
expectedToBeString =
replaceAny<{}>()(Api.callFunctionS("param1", 2, []));
// okay
expectedToBeString =
replaceAny<{}>()(Api.callFunctionN("param1", 2, []));
// error, number not assignable to string
expectedToBeString =
replaceAny<{}>()(Api.callFunctionA("param1", 2, []));
// error, {} not assignable to string

前两个的行为符合您的预期,expectedToBeStringcallFunctionS()感到满意,但对callFunctionN()感到愤怒。 新的行为是它也对callFunctionA()感到愤怒,因为replaceAny<{}>()导致返回值的类型是{}而不是any,并且{}不能分配给string

希望有帮助;祝你好运!

最新更新