我可以帮您进行翻译。这段内容是关于编程的,讲述了如何定义一个鞋子类和一个裙子类。
然后有一个实用类来处理鞋子的移动:
然后有一个通用的移动器,如果用
编译时保证应该是,如果使用
class Shoe {
constructor(public size: number){}
}
class Dress {
constructor(public style: string){}
}
有一个通用的盒子,只能装鞋子或裙子。不能同时装两者:
class Box <T extends Shoe | Dress > {
}
然后有一个实用类来处理鞋子的移动:
class ShoeMover {
constructor(public size: number[]){}
}
还有一个用于移动 Dresses 的实用类:
class DressPacker {
constructor(public style: string[]){}
}
然后有一个通用的移动器,如果用
Box<Shoe>
或 Box<Dress>
实例化,就会有一个 mover
方法,该方法利用 ShoeMover
或 DressPacker
中的一个。class Move<B extends Box<Shoe> | Box<Dress>> {
private box: B;
constructor(toMove: B) {
this.box = toMove;
}
public mover(tool: ShoeMover | DressPacker) {
}
}
编译时保证应该是,如果使用
Box<Shoe>
实例化 Move
,则 mover
方法只应接受 ShoeMover
。如果使用 Box<Dress>
实例化,mover
方法应该只接受 DressPacker
。也就是说:let shoemover = new Move(new Box<Shoe>());
// compile
shoemover.mover(new ShoeMover([21]))
// should not compile. But currently does
shoemover.mover(new DressPacker(["1"]))
我尝试使用条件类型,但是我猜测泛型的参与使得预期解决方案无法工作。基本上这就是我尝试过的:
type MoverFromEitherShoeOrDressA<T> =
T extends Box<infer U> ?
U extends Shoe ? ShoeMover :
U extends Dress ? DressPacker :
never:
never;
and
type MoverFromEitherShoeOrDressB<T> =
T extends Box<Shoe> ? ShoeMover:
T extends Box<Dress> ? DressPacker:
never;
然后将 mover
的定义从以下内容更改为:
public mover(tool: ShoeMover | DressPacker) {
}
到
public mover(tool: MoverFromEitherShoeOrDressB) {
}
or
public mover(tool: MoverFromEitherShoeOrDressA) {
}
...但是它们没有给我所需要的编译时保证。
有人知道如何实现这个?
编辑。
接受的答案适用于上述情况。但是存在一个略微不同的情况,该情况无法工作。我决定更新而不是创建另一个问题。该情况是当Move
的构造函数更改为接受联合类型时。
type Mover<T> =
T extends Shoe ? ShoeMover :
T extends Dress ? DressPacker :
never;
class Move<T extends Shoe | Dress> {
private box: Box<T>;
constructor(public toMove: Box<Shoe>[] | Box<Dress>[]) {
this.box = toMove;
}
public mover(tool: Mover<T>) {
}
}
let shoemover = new Move(new Array<Box<Shoe>>());
// compile
shoemover.mover(new ShoeMover([21]))
// should not compile. But currently does
shoemover.mover(new DressPacker(["1"]))
{{link1:游乐场链接}}
move
构造函数像这样:constructor(public toMove: Box<Shoe>[] | Box<Dress>[])
// 因为 move 可以移动多个鞋盒或衣服盒的盒子。 - Finlay Weber