TypeScript optional type 和 type 的区别 |不明确的

Difference between TypeScript optional type and type | undefined

我很难理解将字段定义为 string | undefinedstring?

之间的区别

我们当前的代码使用这样的类型定义:

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