TypeScript optional type 和 type 的区别 |不明确的
Difference between TypeScript optional type and type | undefined
我很难理解将字段定义为 string | undefined
和 string?
之间的区别
我们当前的代码使用这样的类型定义:
class Foo {
public bar: string | undefined;
}
当 运行 此代码通过 TSLint 时,它会注意到并抱怨它:
Consider using '?' syntax to declare this property instead of 'undefined' in its type.
现在的问题是使用 ?
语法的效果是否完全相同,或者是否存在我遗漏的细微差别?
class Foo {
public bar?: string;
}
所以我们现在如何使用 string | undefined
类型是在这样的检查中:
if (foo.bar) {..}
这会改变吗?
打字稿文档似乎深入探讨了可选类型,但并未真正探讨其在 class 上下文中的行为方式。
bar: string | undefined
:必须声明属性,它可以是字符串或undefined
。
bar?: string
:属性可以不声明;如果它被宣布之前看到。
bar?: string
是可选的 属性,而 bar: string | undefined
是必需的:
interface Foo {
bar?: string
}
interface Foo2 {
bar: string | undefined
}
const foo: Foo = {} // OK
const foo2: Foo2 = {} // error, bar is required
const foo2: Foo2 = {bar: undefined} // OK
关于这个案例:
if (foo.bar) {..}
两种方法都可以(包括 Intellisense 以任何一种方式工作)。
同上答案,附代码示例
// optional property, may be skipped
type Foo = {
bar?: string; // i.e. string | undefined, optional
};
const a: Foo = {
bar: undefined, // ok
};
const a2: Foo = { } // also ok
const a3: Foo = {
bar: null, // ERROR!! Must be string OR undefined
};
const a4: Foo = {
bar: 'sup', // ok, obviously
};
// --------------------
// property is NOT optional, must be declared
type Foo2 = {
bar: string | undefined; // REQUIRED
}
const b: Foo2 = { } // ERROR!!
const b2: Foo2 = {
bar: undefined, // ok
};
const b3: Foo2 = {
bar: null, // ERROR!! Must be string OR undefined
};
const b4: Foo2 = {
bar: 'sup', // ok, obviously
};
在运行时处理这些类型也存在差异:
const a1 = { b: undefined }
Object.keys(a1).forEach(k => console.log(k))
// CONSOLE: b
const a2 = {}
Object.keys(a2).forEach(k => console.log(k))
// CONSOLE:
从 Typescript 4.4 开始,您可以使用 exactOptionalPropertyTypes
选项使可选属性与 type | undefined
更加不同。
默认情况下,Typescript 实际上会处理这个...
interface Person {
name: string;
age?: number;
}
...和这个一样...
interface Person {
name: string;
age?: number | undefined;
}
换句话说,?
实际上 添加了 undefined 到类型定义中,此外还允许您忽略 属性。这些分配中的任何一个都是可以接受的:
const tom: Person = {name: "tom", age: 53};
// This is allowed because of `?`, which adds `undefined` to the type
const john: Person = {name: "john", age: undefined};
// This is allowed because of `?`
const mary: Person = {name: "mary"};
但是当使用exactOptionalPropertyTypes
时,第二个是可选类型不允许的:
const tom: Person = {name: "tom", age: 53};
// This is NOT allowed with just `?`. You have to explicitly add `undefined` to the type
const john: Person = {name: "john", age: undefined};
// This is allowed because of `?`
const mary: Person = {name: "mary"};
有关详细信息,请参阅 typescript 4.4 release notes。
我很难理解将字段定义为 string | undefined
和 string?
我们当前的代码使用这样的类型定义:
class Foo {
public bar: string | undefined;
}
当 运行 此代码通过 TSLint 时,它会注意到并抱怨它:
Consider using '?' syntax to declare this property instead of 'undefined' in its type.
现在的问题是使用 ?
语法的效果是否完全相同,或者是否存在我遗漏的细微差别?
class Foo {
public bar?: string;
}
所以我们现在如何使用 string | undefined
类型是在这样的检查中:
if (foo.bar) {..}
这会改变吗?
打字稿文档似乎深入探讨了可选类型,但并未真正探讨其在 class 上下文中的行为方式。
bar: string | undefined
:必须声明属性,它可以是字符串或undefined
。
bar?: string
:属性可以不声明;如果它被宣布之前看到。
bar?: string
是可选的 属性,而 bar: string | undefined
是必需的:
interface Foo {
bar?: string
}
interface Foo2 {
bar: string | undefined
}
const foo: Foo = {} // OK
const foo2: Foo2 = {} // error, bar is required
const foo2: Foo2 = {bar: undefined} // OK
关于这个案例:
if (foo.bar) {..}
两种方法都可以(包括 Intellisense 以任何一种方式工作)。
同上答案,附代码示例
// optional property, may be skipped
type Foo = {
bar?: string; // i.e. string | undefined, optional
};
const a: Foo = {
bar: undefined, // ok
};
const a2: Foo = { } // also ok
const a3: Foo = {
bar: null, // ERROR!! Must be string OR undefined
};
const a4: Foo = {
bar: 'sup', // ok, obviously
};
// --------------------
// property is NOT optional, must be declared
type Foo2 = {
bar: string | undefined; // REQUIRED
}
const b: Foo2 = { } // ERROR!!
const b2: Foo2 = {
bar: undefined, // ok
};
const b3: Foo2 = {
bar: null, // ERROR!! Must be string OR undefined
};
const b4: Foo2 = {
bar: 'sup', // ok, obviously
};
在运行时处理这些类型也存在差异:
const a1 = { b: undefined }
Object.keys(a1).forEach(k => console.log(k))
// CONSOLE: b
const a2 = {}
Object.keys(a2).forEach(k => console.log(k))
// CONSOLE:
从 Typescript 4.4 开始,您可以使用 exactOptionalPropertyTypes
选项使可选属性与 type | undefined
更加不同。
默认情况下,Typescript 实际上会处理这个...
interface Person {
name: string;
age?: number;
}
...和这个一样...
interface Person {
name: string;
age?: number | undefined;
}
换句话说,?
实际上 添加了 undefined 到类型定义中,此外还允许您忽略 属性。这些分配中的任何一个都是可以接受的:
const tom: Person = {name: "tom", age: 53};
// This is allowed because of `?`, which adds `undefined` to the type
const john: Person = {name: "john", age: undefined};
// This is allowed because of `?`
const mary: Person = {name: "mary"};
但是当使用exactOptionalPropertyTypes
时,第二个是可选类型不允许的:
const tom: Person = {name: "tom", age: 53};
// This is NOT allowed with just `?`. You have to explicitly add `undefined` to the type
const john: Person = {name: "john", age: undefined};
// This is allowed because of `?`
const mary: Person = {name: "mary"};
有关详细信息,请参阅 typescript 4.4 release notes。