HOWTO · TypeScript

TypeScript 中的接口默认值

TypeScript 接口定义的是编译期对象形状,而不是运行时默认值。请使用可选属性,并在运行时代码中应用回退值。

本页内容

接口不能赋予默认值:它描述对象在 TypeScript 编译期检查中的形状,并会从生成的 JavaScript 中移除。若要使用默认值,可以将可配置属性标记为可选属性,再在运行时代码中应用回退值,例如通过函数构建完整配置。

TypeScript 中的 Interface 是什么

TypeScript 使用结构类型系统:对象只要具有接口要求的属性,且属性类型兼容,就符合该接口。因此,接口是编译期契约,而不是构造函数或运行时对象。例如,interface LabeledValue { label: string } 描述了会读取 label 的函数所接受的对象形状;只要对象有一个字符串类型的 label,即使它还包含其他属性,也符合该契约。声明的类型可以帮助编译器在编写代码时检查代码,但编译完成后,它不会作为 JavaScript 值存在。如果应用收到 JSON 或其他外部值,应先单独验证这些数据,再将其视为 LabeledValue。

接口不会创建值,因此,在接口中声明属性并不会初始化该属性。必须由类构造函数、函数或其他 JavaScript 代码创建或修改实际对象。理解这一区别,是掌握如何为接口所描述的对象提供默认值的关键。

使用可选属性为 TypeScript 中的 Interface 设置默认值

在 TypeScript 中,可选属性允许调用方省略某些值,而默认值则由运行时代码应用。下面的纯语法 TypeScript 示例声明了 SquareConfig,为函数参数指定类型,并传入一个属性名称拼错的新对象字面量:

interface SquareConfig { color?: string; width?: number }; function createSquare(config: SquareConfig) { return config; }; createSquare({ clor: "black" });

编译器会指出,clor 不是 SquareConfig 的已知属性;将其改为 color 后,就符合声明的对象形状。这项编译期检查可以在调用处发现拼写错误,但接口不会添加默认值,也不会验证任意运行时数据。下面的 JavaScript 示例则展示了运行时代码如何应用回退值,它与 TypeScript 类型检查是两回事。

这个 JavaScript 示例展示了运行时代码如何应用默认设置和自定义设置。示例是完整独立的,并使用空值合并运算符:当值为 null 或 undefined 时选择回退值,其他已提供的值则会保留。

function createSquare(config) {
  const color = config.color ?? "white";
  const width = config.width ?? 10;
  return { color, area: width * width };
}

const defaultSquare = createSquare({});
const customSquare = createSquare({ color: "black", width: 5 });

console.log(JSON.stringify(defaultSquare));
console.log(JSON.stringify(customSquare));
{"color":"white","area":100}
{"color":"black","area":25}

可选属性不会自动生成默认值,因此应在构造对象的函数(或其他运行时操作)中设置回退值。返回完整对象能让后续代码获得明确的结果形状,其中 color 和 area 都是必需属性。如果 0、false 或空字符串也应触发回退,可以改用真值判断(||);应根据属性允许包含的值来选择方式。读取属性之前,函数参数应当是一个对象。若要根据可选的外部输入构建配置,请先规范化或验证输入,再将完整对象传给应用的其余部分。