TypeScript中的可选参数可以为空吗?

82
根据这篇文章,在TypeScript中启用了严格的null检查后,除非使用联合类型显式地允许,否则无法将nullundefined赋值给变量。
// required value
let req: string;
req = "Something";  // OK
req = null;      // Error
req = undefined; // Error

// nullable value
let nbl: string | null;
nbl = "Something";  // OK
nbl = null;      // OK
nbl = undefined; // Error

但是在 TypeScript 的 可选值 中是否允许使用 null

Translated Text:

但是在 TypeScript 的 可选值 中是否允许使用 null

// optional value
let opt?: string; // (actually invalid, as optional types cannot be used for variable declarations, but that's not the point, so imagine we are dealing with function parameters or something)
opt = "Something"; // OK
opt = null; // OK? Error?
opt = undefined; // OK

还是

opt?: string;

等同于

opt: string | undefined;

因此,不允许null,就像Microsoft编码指南建议的一样吗?

2个回答

135

编辑:重要提示 正如Quentin C在下面的评论中指出的那样,这里列出的行为仅在启用严格的空值检查时才会发生:"strictNullChecks": truetsconfig.json 中。


nullundefined 类型被视为不同的类型。而可选类型是特殊的,它还允许函数调用时省略参数。

1. 如果没有联合类型或可选类型,那么除了该类型本身,其他任何类型都不允许。

function foo(bar: string) {
    console.info(bar);
}

foo("Hello World!"); // OK
foo(null); // Error
foo(undefined); // Error
foo() // Error

2. 要额外允许 null,可以使用包含 null 的联合类型。

function foo(bar: string | null) {
    console.info(bar);
}

foo("Hello World!"); // OK
foo(null); // OK
foo(undefined); // Error
foo() // Error

3. 允许 undefined 的使用方式类似。请注意,参数不能省略或设置为 null

function foo(bar: string | undefined) {
    console.info(bar);
}

foo("Hello World!"); // OK
foo(null); // Error
foo(undefined); // OK
foo() // Error

4. 你也可以同时允许两种情况,但必须仍然提供参数。

function foo(bar: string | null | undefined) {
    console.info(bar);
}

foo("Hello World!"); // OK
foo(null); // OK
foo(undefined); // OK
foo() // Error

5. 通过使用可选参数,您可以不传递该参数或传递 undefined,但不能传递 null

解释:在使用可选参数时,可以选择不传递该参数或传递未定义的值,但不能传递空值。
function foo(bar?: string) {
    console.info(bar);
}

foo("Hello World!"); // OK
foo(null); // Error
foo(undefined); // OK
foo() // OK

6. 为允许所有三种特殊情况,optionalnull可以组合使用。

function foo(bar?: string | null) {
    console.info(bar);
}

foo("Hello World!"); // OK
foo(null); // OK
foo(undefined); // OK
foo() // OK

同样,optional只能在参数或其他类型声明中使用,比如接口,而不能用于普通变量。因为在给变量赋值时省略值是毫无意义的。

因此,

let d?: string;

这样做没有意义,并会导致编译错误。


8
对于像我这样不太认真阅读问题的人,这里列出的行为仅在启用了严格的空值检查时才会发生。在tsconfig.json中,“strictNullChecks”: true。 - Quentin C
请注意,在 tsconfig.js 中指定了 "exactOptionalPropertyTypes": true 时,示例 #5 中不允许使用 undefined - Allon Guralnek

-3

let d?: string;声明类型为string | undefined

这是因为undefined是JS变量的默认值。


2
你是不正确的,let d?: string在TypeScript中是无效的。请参阅https://github.com/microsoft/TypeScript/issues/13321。 - Karel Kral

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接