我有一个名为Bounds
的接口,还有一个Sprite
类,其类型为bounds
的字段Bounds[][]
。 Sprite
的{{1}}的联合类型参数为constructor
。如果参数的类型为Bounds[]|Bounds[][]
,我想将其包装在一个数组中:
Bounds[]
此代码有效,但是TypeScript编译器分别给我第二和第三次分配这些错误:
class Sprite {
constructor(bounds: Bounds[]|Bounds[][]) {
if (!bounds) {
this.bounds = [[ /* some default value */ ]];
} else {
if (!bounds.length) {
throw new Error('Argument \'bounds\' must not be empty.');
}
if (!Array.isArray(bounds[0])) {
this.bounds = [bounds];
} else {
this.bounds = bounds;
}
}
}
bounds: Bounds[][];
}
我如何明确告诉编译器“此时Type '(Bounds[] | Bounds[][])[]' is not assignable to type 'Bounds[][]'.
Type 'Bounds[] | Bounds[][]' is not assignable to type 'Bounds[]'.
Type 'Bounds[][]' is not assignable to type 'Bounds[]'.
Type 'Bounds[]' is not assignable to type 'Bounds'.
Property 'x' is missing in type 'Bounds[]'.
Type 'Bounds[] | Bounds[][]' is not assignable to type 'Bounds[][]'.
Type 'Bounds[]' is not assignable to type 'Bounds[][]'.
Type 'Bounds' is not assignable to type 'Bounds[]'.
Property 'length' is missing in type 'Bounds'.
是bounds
类型还是Bounds[]
类型或使用正确的if语句,以便编译器可以到达这个结论本身吗?
答案 0 :(得分:2)
如果您想帮助编译器进行推理,可以使用自定义类型防护:
const isArrayOfArrays = <T>(b: T[] | T[][]):b is T[][] => Array.isArray(b[0]);
class Sprite {
constructor(bounds: Bounds[]|Bounds[][]) {
if (!bounds) {
this.bounds = [[ /* some default value */ ]];
} else {
if (!bounds.length) {
throw new Error('Argument \'bounds\' must not be empty.');
}
if (!isArrayOfArrays(bounds)) {
this.bounds = [bounds];
} else {
this.bounds = bounds;
}
}
}
bounds: Bounds[][];
}
类型防护程序可在任何此类情况下重用。
懒惰的方法是只使用类型断言,然后告诉编译器您对类型的了解:
class Sprite {
constructor(bounds: Bounds[] | Bounds[][]) {
if (!bounds) {
this.bounds = [[ /* some default value */]];
} else {
if (!bounds.length) {
throw new Error('Argument \'bounds\' must not be empty.');
}
if (!Array.isArray(bounds[0])) {
this.bounds = [bounds as Bounds[]];
} else {
this.bounds = bounds as Bounds[][];
}
}
}
bounds: Bounds[][];
}