在Typescript中使用'--strictFunctionTypes'有什么好处?

时间:2018-08-09 12:41:05

标签: typescript interface strict compiler-options

据我了解,Typescript中的--strictFunctionTypes编译器选项阻止了多态的一种非常常见的使用案例:

type Handler = (request: Request) => Response

const myHandler: Handler = (request: Request & { extraArg: boolean }) => {
  return !!request.extraArg
}

通常,我假设strict系列中的所有编译器选项都有一些好处,但是在这种情况下,我所看到的只是它阻止了非常逻辑的行为。

那么在什么情况下此选项实际上可以带来一些好处?它可以防止哪些有害情况?

2 个答案:

答案 0 :(得分:6)

在没有strictFunctionTypes的情况下导致运行时错误实际上非常容易。

让我们考虑以下示例:

type Handler = (request: Request) => Response

const myHandler: Handler = (request: Request & { extraArg: string }) => {
    // extraArg is required so need to check for null
    request.extraArg.toUpperCase();
    return null as any;
}

declare let r: Request; // comes from sowhere 
myHandler(r); // no need to pass in the extraArg not required by the signature

因此在上面的示例中,函数签名需要一个Request,因此我们只需要传递Request。但是该实现期望接收其中需要Request & { extraArg: string }的{​​{1}},并且无需进行检查即可访问它(毕竟,如果需要,被调用者应该将其传递进来)。

这是extraArg防止的错误类型。如果签名中的参数是基本类型,而实现需要一个派生类型,则不能保证实现将接收派生类型,因为签名仅要求将基本类型传入

答案 1 :(得分:3)

我认为此选项修复了TypeScript编译器中的错误。如果不是错误,那么那只是一个错误的设计决定,新编译器选项的出现证明了我的意思。让我们从一个示例开始,默认情况下,下一个代码将毫无问题地进行编译:

// Focus all your attention on callback signature
// It has date parameter which is a union type
function getCurrentYear(callback: (date: string | number) => void) {
   callback((Math.random() > 0.5) ? '2020' : 2020);
}

// note that we ignored the fact that in 50% cases our callback returns string type instead of number.
getCurrentYear((date: string) => {
    console.log(date.charAt(0)); // in 50% it is RUNTIME ERROR
});

因此,传递给getCurrentYear的箭头函数缩小了“ date”参数的类型,而TypeScript对此并不在乎。但是,即使在没有任何严格规则的情况下,具有变量的不同上下文中的相同技巧也会产生错误:

let x: string | number = (Math.random() > 0.5) ? '2020' : 2020;
const y: number = x; // COMPILE TIME ERROR

这更有意义,启用--strictFunctionTypes将要求编译器在回调函数中遵循相同的行为。无疑,这将有助于您防止大型项目中的某些错误。

来源:

https://medium.com/javascript-in-plain-english/what-are-these-strict-compiler-options-in-typescript-part-2-a7e974b13e54