Ell*_*tch 5 interface optional-parameters typescript
在 Javascript 中,我喜欢将 an 传递options object给 a constructor ,并用默认值填充我期望的任何缺失属性:
function foo(options) {
if(options.a == undefined) {
options.a = 1;
}
if(options.b == undefined) {
options.b = 'hello';
}
this.options = options;
}
new foo({a: 10});
Run Code Online (Sandbox Code Playgroud)
尝试在 Typescript 中实现此模式,我有:
interface Options {
a?: number;
b?: string;
}
class Foo {
options: Options;
constructor(options: Options) {
if(options.a == undefined) {
options.a = 1;
}
if(options.b == undefined) {
options.b = 'hello';
}
this.options = options;
}
}
Run Code Online (Sandbox Code Playgroud)
当我options在class后面使用时,我知道所有的属性都被定义了。但是,Typescript 不知道这一点,因此此语句会产生错误:
let a:Number = this.options.a; // Argument of type 'number | undefined' is not assignable to parameter of type number.
Run Code Online (Sandbox Code Playgroud)
此外,我不想让 中的代码稍后为该属性class分配null或值:undefined
this.options.a = undefined; // should produce compiler error
Run Code Online (Sandbox Code Playgroud)
有没有办法定义我的类型,以便在不定义两个接口的Options情况下使用时, 的属性不能为空?class Options
例如,我知道我可以制作另一个interface供内部使用:
interface OptionsSafe {
a: number;
b: string;
}
// in Foo constructor
this.options = {
a: a != undefined ? options.a! : 1,
b: b != undefined ? options.b! : 'hello'
};
Run Code Online (Sandbox Code Playgroud)
但随后我需要在两个单独的接口中定义选项的属性,并确保它们始终保持同步(如果 Typescript 可以从一个定义生成两个接口,那么这个解决方案会很棒)。
我也不想将所有属性作为单独的可选参数传递,因为
Options接口,所以我仍然必须保持两个“接口”同步。Partial一种选择是使用Typescript 提供的内置类型。对于您来说,这可能太接近“定义两个Options接口”,但无论如何我都会向您展示我的意思。
Typescript 提供了一个内置类型Partial,定义为type Partial<T> = {[P in keyof T]?: T[P]}.
这意味着您可以做的只是定义Options包含所有成员的接口,但将其部分版本用于构造函数。像这样:
interface Options {
a: number;
b: string;
}
class Foo {
options: Options;
constructor(options: Partial<Options>) {
const defaultOptions = {
a: 1,
b: 'hello'
};
this.options = Object.assign(defaultOptions, options);
}
}
Run Code Online (Sandbox Code Playgroud)
为了让 Typescript 正确推断您已经获得了对象的所有必要属性,您需要从if您使用的语句逻辑转向类似于上面的逻辑。