【问题标题】:What is the benefit of using '--strictFunctionTypes' in Typescript?在 Typescript 中使用“--strictFunctionTypes”有什么好处?
【发布时间】:2019-01-16 22:30:32
【问题描述】:

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

type Handler = (request: Request) => Response

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

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

那么在哪些情况下这个选项实际上会带来一些好处?它可以防止哪些有害场景?

【问题讨论】:

标签: typescript interface strict compiler-options


【解决方案1】:

在我看来,此选项修复了 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 的箭头函数缩小了“日期”参数的类型,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

【讨论】:

  • 我对这里的示例代码感到困惑,因为getCurrentYear 实际上并没有使用回调。在我看来,这不是为了您的演示目的。
  • @g.delgado 你是对的。有一个错字。更新代码
【解决方案2】:

如果没有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 },其中需要extraArg,并且无需检查即可访问它(毕竟,如果需要,被调用者应该已将其传入)。

这是strictFunctionTypes 防止的错误类型。如果签名中的参数是基类型,而实现需要派生类型,则无法保证实现将接收派生类型,因为签名只需要传入基类型

【讨论】:

    猜你喜欢
    • 2019-02-06
    • 2019-01-23
    • 1970-01-01
    • 2012-01-21
    • 2011-01-15
    • 2016-01-30
    • 2018-01-22
    • 2016-06-27
    • 2016-11-05
    相关资源
    最近更新 更多