我正在使用打字稿开发应用程序的用户界面。 与此同时,其他人也在努力向我提供数据。 我们就数据合同达成了一致,但是该过程很容易出错,并且我不断从服务器获取无效的数据对象。所以我的问题是我可以使用打字稿中定义的一些接口以某种方式验证动态对象(在运行时)吗?
编写一些工具将 TypeScript 接口转换为某种运行时对象表示形式,您可以使用它来验证对象,或者:
正如 Brian 指出的那样,接口仅在编译时显现出来,并被编译器用作所谓的“命名类型”。语言规范第 7 节对此进行了如下描述:
接口没有运行时表示——它们纯粹是编译时构造。接口对于记录和验证所需的属性形状、作为参数传递的对象以及从函数返回的对象特别有用。
在规范的第 7.4 节中,有一个关于 Typescript 中动态类型检查的很好的描述:TypeScript 不提供动态测试对象是否实现特定接口的直接机制。相反,TypeScript 代码可以使用 JavaScript 技术来检查对象上是否存在适当的成员集......
interface Mover { move(): void; getStatus(): {speed: number;}; } interface Shaker { shake(): void; getStatus(): {frequency: number;}; } interface MoverShaker extends Mover, Shaker { getStatus(): { speed: number; frequency: number; }; }
MoverShaker
将
Mover
和
Shaker
组合成一个新的复合界面。要在运行时验证给定类型是否满足接口
MoverShaker
,您可以使用 Javascript 代码,如下所示:var obj: any = getSomeObject();
if (obj && obj.move && obj.shake && obj.getStatus) {
var moverShaker = <MoverShaker> obj;
...
}
为了在 Typescript 中进行编译时检查,您需要为应用程序的两个部分之间交换的类型定义接口。目前,您必须手动编写动态检查代码(如上所述)。因此,如果您忘记同步更新静态类型和动态检查代码,它们在某些时候可能会出现偏差。正如 Brian 指出的,如果有一个自动生成代码的工具就好了。 如果您愿意,请尝试我的动态界面检查器,这是一个示例(完整示例
):
interface PhysicalObject { color : Color; intact : bool; weight : number; }
class Car implements PhysicalObject {
public intact = true;
constructor(public color : Color, public weight : number) {};
}
function scratch(aCar : Car) {
typeCheck(JSVenv, arguments, schemas, ["PhysicalObject"]);
console.log("Scratching the car!");
aCar.intact = false;
}
scratch({ intact: 42, color: Color.RED })
的代码时,会抛出这样的错误:
AssertionError: Runtime typecheck failed on argument number 1:
Value: { color: 0, weight: 'four', intact: true },
Schema: ...,
Error reports (length 1):
[
{
uri: 'urn:uuid:b9b8e6fd-b14b-490d-9372-d2bd22e8a246#/weight',
schemaUri: 'urn:uuid:c76ddd92-15da-43a6-831e-6717f253efe5#/properties/weight',
attribute: 'type',
message: 'Instance is not a required type',
details: [ 'number' ]
}
]
请参阅主页以获取说明:https://github.com/ysangkok/typescript-interface-to-jsonschema
我会添加自动类型检查,但我需要类似 node-falafel
的 TypeScript。