我正在使用Typescript,我想编写一个带有可选参数的函数。我不确定这是否是个合适的地方,因为没有问题,但这与编写干净的代码有关:
public addResource(config?: ResourceConfig): void {
if (!config) {
config = {} as ResourceConfig;
}
const resource: FormGroup = this.createResource(config);
this.control.push(resource);
}
private createResource({ amount, profit, load }: ResourceConfig): FormGroup {
return new FormGroup({
amount: new FormControl(amount || 1),
profit: new FormControl(profit || 1),
load: new FormControl(load || 1)
});
}
...
interface ResourceConfig {
amount: number;
profit: number;
load: number;
}
答案 0 :(得分:0)
我假设您正在使用--strictNullChecks
编译器选项,如果没有,则应该使用。
我认为可选参数本身不是问题,但是从您的使用看来,您似乎希望传递给ResourceConfig
和addResource()
的{{1}}对象的各个属性可能是失踪。但是这些方法的签名没有这么说。这会导致您不得不回避TypeScript的类型系统而不是使用它的情况。
特别是,行createResource()
有问题。实际上,您已经使用type assertion对编译器撒谎了,因为空对象config = {} as ResourceConfig;
不是{}
。有时候,对编译器来说,小的谎言很有用,特别是在它们只是临时的情况下(例如,如果在那一行之后您继续在最初为空的对象中设置所有属性)。但是在这种情况下,您永远不会填充ResourceConfig
的属性,因此欺骗会传递到config
方法中……其中createResource()
,amount
和{{1} }编译器认为}变量为profit
,但实际上在运行时可能为load
。您可以通过检查falsiness的每个值来解决这种可能性,但是如果我相信类型系统的话,这似乎是不必要的。
有不同的处理方法。一种就是说number
缺少某些属性是可以的。这意味着您实际上没有undefined
,而是拥有config
,其中ResourceConfig
是标准库中的mapped type,其definition是
Partial<ResourceConfig>
所以Partial<T>
等同于
type Partial<T> = { [P in keyof T]?: T[P] };
相反,您将获得:
Partial<ResourceConfig>
其中不需要类型声明,并且编译器将{
amount?: number;
profit?: number;
load?: number;
}
中的变量称为public addResource(config?: Partial<ResourceConfig>): void {
if (!config) {
config = {}; // truth
}
const resource: FormGroup = this.createResource(config);
this.control.push(resource);
}
private createResource({ amount, profit, load }: Partial<ResourceConfig>): FormGroup {
return new FormGroup({
amount: new FormControl(amount || 1),
profit: new FormControl(profit || 1),
load: new FormControl(load || 1)
});
}
,并且将传递给createResource
构造函数的参数也称为由于number | undefined
的欺骗而成为FormControl
。
处理此问题的另一种方法是实际上要求number
是|| 1
,如果未定义,则为其分配有效的config
:
ResourceConfig | undefined
这使ResourceConfig
不必担心可能的public addResource(config?: ResourceConfig): void {
if (!config) {
config = {
amount: 1,
profit: 1,
load: 1
};
}
const resource: FormGroup = this.createResource(config);
this.control.push(resource);
}
private createResource({ amount, profit, load }: ResourceConfig): FormGroup {
return new FormGroup({
amount: new FormControl(amount),
profit: new FormControl(profit),
load: new FormControl(load)
});
}
变量。如果要允许createResource()
,undefined
或amount
为零,则这种方法可能更好。请注意,profit
等于load
,因为0 || 1
是虚假的。如果您不希望1
神奇地变成0
,则不能使用0
技巧。
无论哪种方式都行得通,并且存在许多其他解决方案。这里的主要思想是尝试利用TypeScript的类型系统,而不是规避它。
好的,希望能有所帮助。祝你好运!