TypeScript 中使用接口的默认值

要在 TypeScript 中为接口设置默认值,请创建一个初始化函数,它定义类型的默认值,并使用扩展语法 … 用用户提供的值覆盖默认值。

interface Person {
  name: string;
  age: number;
  country: string;
}

function initPerson(options?: Partial<Person>): Person {
  const defaults = {
    name: '',
    age: 0,
    country: '',
  };

  return {
    ...defaults,
    ...options,
  };
}

const p1: Person = initPerson();

console.log(p1); // ?️ {name: '', age: 0, country: ''}

const p2: Person = initPerson({ name: 'Tom', age: 30 });
console.log(p2); // ?️ {name: 'Tom', age: 30, country: ''}

我们创建了一个 initPerson 函数,可以使用选项对象或根本没有参数来调用它。

该函数定义 Person 接口的默认值,并使用扩展语法 … 在解包任何用户提供的值之前解包默认值。

我们使用 Partial 实用程序类型在函数参数中将 Person 接口中的所有属性设置为可选。

函数传递的任何值都将覆盖默认值。

const obj1 = {
  name: 'Tom',
};

const obj2 = {
  name: 'Alfred',
};

const obj3 = {
  ...obj1,
  ...obj2,
};

console.log(obj3); // ?️ {name: 'Alfred'}

当使用相同的键解压多个对象时,最后解压的对象会覆盖之前的值。

如果要将接口的属性设置为默认值 undefined,只需将属性设置为可选即可。

interface Person {
  name?: string;
  age?: number;
  country: string;
}

const p1: Person = {
  country: 'Germany',
};

// ?️ Rest are optional

p1.age = 30;

p1.name = 'Tom';

我们使用问号将 name 和 age 属性标记为可选。

现在我们不需要在创建使用 Person 接口的对象时设置它们。

我们可以在稍后阶段使用点或括号表示法设置对象的属性。

即使 TypeScript 不要求我们在创建对象时设置 name 和 age 属性,它仍然会检查以后添加的任何属性是否符合 Person 接口。

interface Person {
  name?: string;
  age?: number;
  country: string;
}

const p1: Person = {
  country: 'Germany',
};

// ⛔️ Error: Property 'test' does not exist on type 'Person'
p1.test = 'hello';

// ⛔️ Error: Type '5' is not assignable to type 'string' or 'undefined'
p1.name = 5;

我们只能添加在接口上定义并匹配指定类型的属性。