Typescript 基于先前方法调用的方法签名
我需要根据不同的步骤编写一个值转换程序。为了重用这些步骤,提出了一种架构,其中可以将这些步骤传递给转换,类似于此代码(例如,将长字符串大写并在13个字符后截断): 是否有办法确保(最好是在编译时)这些步骤彼此兼容,即一个步骤的输出与下一个步骤的输入类型兼容,因此在生成字符串的步骤之后不允许使用以下类:Typescript 基于先前方法调用的方法签名,typescript,Typescript,我需要根据不同的步骤编写一个值转换程序。为了重用这些步骤,提出了一种架构,其中可以将这些步骤传递给转换,类似于此代码(例如,将长字符串大写并在13个字符后截断): 是否有办法确保(最好是在编译时)这些步骤彼此兼容,即一个步骤的输出与下一个步骤的输入类型兼容,因此在生成字符串的步骤之后不允许使用以下类: class SquareRoot { public run(num: number): number { return Math.sqrt(num); } } 通过将两个成员in
class SquareRoot {
public run(num: number): number {
return Math.sqrt(num);
}
}
通过将两个成员
inputType
和outputType
添加到步骤中并进行比较,在运行时实现这一点似乎是可能的,但我希望在编译时进行检查。首先,让我们定义Transformer
类
class Transformation<T> {
constructor(readonly value: T) {
this.value = value;
}
public static from<U>(input: U): Transformation<U> {
return new Transformation(input);
}
public step<U>(transformer: Transformer<T, U>): Transformation<U> {
return new Transformation(transformer.run(this.value));
}
}
有了它,就可以保证转换在编译时是正确的
Transformation.from("This is a long story")
.step(new Uppercase())
.step(new Truncate()); // OK
Transformation.from("This is a long story")
.step(new Uppercase())
.step(new SquareRoot()); // Compile-time error: Type 'string' is not assignable to type 'number'.ts(2345)
更新
注意:在您的示例中,您将大写
和截断
的构造函数作为步骤
传递。在我的解决方案中,使用了实例。如果坚持要传递构造函数,则需要将run
方法设置为静态
class Uppercase {
public static run(str: string): string {
return str.toUpperCase();
}
}
class Truncate {
public static run(str: string): string {
return str.substr(0, 10) + '...';
}
}
class SquareRoot {
public static run(num: number): number {
return Math.sqrt(num);
}
}
Transformation.from("This is a long story")
.step(Uppercase)
.step(Truncate);
Transformation.from("This is a long story")
.step(Uppercase)
.step(SquareRoot); // Compile-time error: Type 'string' is not assignable to type 'number'.ts(2345)
很好的解决方案。我用一种非常相似的方法解决了它。您可以在stackblitz上看到它:在那里您可以看到不需要为step类创建静态方法。还可以使用
step(transformer:{new():T})
并在函数中实例化它。哇,太棒了。顺便说一句,实例工作得很好。构造函数是早期尝试的遗物,但决不是必需的。
Transformation.from("This is a long story")
.step(new Uppercase())
.step(new Truncate()); // OK
Transformation.from("This is a long story")
.step(new Uppercase())
.step(new SquareRoot()); // Compile-time error: Type 'string' is not assignable to type 'number'.ts(2345)
class Uppercase {
public static run(str: string): string {
return str.toUpperCase();
}
}
class Truncate {
public static run(str: string): string {
return str.substr(0, 10) + '...';
}
}
class SquareRoot {
public static run(num: number): number {
return Math.sqrt(num);
}
}
Transformation.from("This is a long story")
.step(Uppercase)
.step(Truncate);
Transformation.from("This is a long story")
.step(Uppercase)
.step(SquareRoot); // Compile-time error: Type 'string' is not assignable to type 'number'.ts(2345)