如何在TypeScript中声明一个类型为空?

我有一个接口在TypeScript。

interface Employee{
id: number;
name: string;
salary: number;
}

我想将salary作为一个可空字段(就像我们在c#中可以做的那样)。这可能在TypeScript中实现吗?

572487 次浏览

只需在可选字段中添加一个问号?

interface Employee{
id: number;
name: string;
salary?: number;
}

JavaScript(和TypeScript)中的所有字段的值都可以是nullundefined

你可以将不同于null的字段可选设为可空。

interface Employee1 {
name: string;
salary: number;
}


var a: Employee1 = { name: 'Bob', salary: 40000 }; // OK
var b: Employee1 = { name: 'Bob' }; // Not OK, you must have 'salary'
var c: Employee1 = { name: 'Bob', salary: undefined }; // OK
var d: Employee1 = { name: null, salary: undefined }; // OK


// OK
class SomeEmployeeA implements Employee1 {
public name = 'Bob';
public salary = 40000;
}


// Not OK: Must have 'salary'
class SomeEmployeeB implements Employee1 {
public name: string;
}

比较:

interface Employee2 {
name: string;
salary?: number;
}


var a: Employee2 = { name: 'Bob', salary: 40000 }; // OK
var b: Employee2 = { name: 'Bob' }; // OK
var c: Employee2 = { name: 'Bob', salary: undefined }; // OK
var d: Employee2 = { name: null, salary: 'bob' }; // Not OK, salary must be a number


// OK, but doesn't make too much sense
class SomeEmployeeA implements Employee2 {
public name = 'Bob';
}

我也有过同样的问题。ts中的所有类型都是可空的,因为void是所有类型的子类型(例如,与scala不同)。

看看这个流程图是否有帮助- https://github.com/bcherny/language-types-comparison#typescript

在我看来,联合类型在这种情况下是最好的选择:

interface Employee{
id: number;
name: string;
salary: number | null;
}


// Both cases are valid
let employe1: Employee = { id: 1, name: 'John', salary: 100 };
let employe2: Employee = { id: 1, name: 'John', salary: null };

编辑:为了使其正常工作,你应该在tsconfig中启用strictNullChecks

为了更像c#,可以这样定义Nullable类型:

type Nullable<T> = T | null;


interface Employee{
id: number;
name: string;
salary: Nullable<number>;
}

奖金:

为了使Nullable表现得像一个内置Typescript类型,在根源文件夹的global.d.ts定义文件中定义它。这个路径适合我:/src/global.d.ts

type MyProps = {
workoutType: string | null;
};

可空类型可以调用运行时错误。 所以我认为使用编译器选项--strictNullChecks并将number | null声明为类型是很好的。同样在嵌套函数的情况下,尽管输入类型是空的,编译器不知道它会破坏什么,所以我建议使用!(感叹号)

function broken(name: string | null): string {
function postfix(epithet: string) {
return name.charAt(0) + '.  the ' + epithet; // error, 'name' is possibly null
}
name = name || "Bob";
return postfix("great");
}


function fixed(name: string | null): string {
function postfix(epithet: string) {
return name!.charAt(0) + '.  the ' + epithet; // ok
}
name = name || "Bob";
return postfix("great");
}
< p >参考。 https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions < / p >

你可以像下面这样实现一个用户定义的类型:

type Nullable<T> = T | undefined | null;


var foo: Nullable<number> = 10; // ok
var bar: Nullable<number> = true; // type 'true' is not assignable to type 'Nullable<number>'
var baz: Nullable<number> = null; // ok


var arr1: Nullable<Array<number>> = [1,2]; // ok
var obj: Nullable<Object> = {}; // ok


// Type 'number[]' is not assignable to type 'string[]'.
// Type 'number' is not assignable to type 'string'
var arr2: Nullable<Array<string>> = [1,2];

我通过编辑tsconfig解决了这个问题。json文件。

< p >下:"strict": true, 添加这两行:

"noImplicitAny": false,
"strictNullChecks": false,
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};

然后你就可以用它了

Nullable<Employee>

这样你仍然可以像在其他地方一样使用Employee接口

type WithNullableFields<T, Fields> = {
[K in keyof T]: K extends Fields
? T[K] | null | undefined
: T[K]
}


let employeeWithNullableSalary: WithNullableFields<Employee, "salary"> = {
id: 1,
name: "John",
salary: null
}

或者你可以关闭strictNullChecks;)

反过来说:

type WithNonNullableFields<T, Fields> = {
[K in keyof T]: K extends Fields
? NonNullable<T[K]>
: T[K]
}