为什么将'null'或'undefined'“可分配”给类型为'string'的参数?

时间:2020-09-24 09:58:52

标签: typescript typescript-generics

让我们有the following code in TypeScript

function f<T>(a: T, b: T) { }

f("a", 1);

TypeScript可能会失败,并显示以下信息:

'number'类型的参数不能分配给'string'类型的参数。

但是,when I pass null (or undefined) instead of 1的TypeScript将通用参数<T>的类型更改为string | null,并且不会失败。

我有两个问题:

  • 为什么nullundefined与例如number
  • 以及如何防止扩展(将类型更改为string | null)?

1 个答案:

答案 0 :(得分:2)

为什么null或undefined与e.g.数字?

说实话,我不确定100%为什么。如评论中所述,它推断a的类型为'string',但允许'null |未定义。我做了一些实验,却不知道为什么要这么做。

以及如何防止扩展(将类型更改为字符串| null)? 您可以做什么的一些示例:

// Original
function f<T>(a: T, b: T) { }

f('a', 'b')  // Allowed
f(1, 2) // Allowed
f(true, false) // Allowed
f("a", 1); // Has error
f("a", undefined); // Allowed
f("a", null); // Allowed
f(null, null) // Allowed

// Extending then defining
// Will only allow strings
function g<T extends string = string>(a: T, b: T) { }

g('a', 'b')  // Allowed
g(1, 2) // Has error
g(true, false) // Has error
g("a", 1); // Has error
g("a", undefined); // Has error
g("a", null); // Has error
g(null, null) // Has error

// Using Required
// Does not allow null or undefined but allows other non strings
function x<T>(a: Required<T>, b: Required<T>) { }

x('a', 'b') // Allowed
x(1, 2) // Allowed
x(true, false) // Allowed
x("a", 1); // Has error
x("a", undefined); // Has error
x("a", null); // Has error
x(null, null) // Has error

https://www.typescriptlang.org/play?ts=4.0.2#code/PTAEHkCcEsHNoHYEMA2AoAZgVwQYwC7QD2CoGAPACoB8AFEgFyiUA0oARk5QJSgDeoAL5pMtAORIxbMezG9QIUAEEUKIgHcApgBNRARjYAmXopVqtujLXyQsmthlQBnTSbBmNO0QCIk3tnrcANwKYAASSE6gmpCQRJA+fmw42poYiDrBocqqnpa0vv6gCFiqWaa5FqIlqmw1KG455l5oigCiAB74mgjaiLCg+AAWPaCp6Qj9rWAA6tCqoCQoAJ6gqOagTjb9Tpg4BMSksFTRXT3aUVswCAMAvJvbN3SMzGyczLwCwmiw4pLSsnkFWaul+BlAxmyESiMTiCV+NjsDmcrihkWisXiPwKSVAgRCimhGLh2MKyV6aQy2nK4XRsKxvzJxVKDQJtJhmPhtHqdRZjSJ9IS01AAFUnP1QAAlTQARyw0EgXkUABEiJooggiPg1pVmQt4qAUpSEDoOFhtesNFEtSNIMUSA9rrBdtg8IQHR0qM8mNK5QqdF63j7ZfLFdovZ8hCIOn8pKAZHJsh4qjHwZDgXk0DHEfYyCjGsmvDGmfi0RyScXcUaJpk2aABZysziivUafW6Y2Yzy9Q0y8SsUA