我正在使用打字稿处理应用程序的 UI。与此同时,其他人也在努力为我提供数据。我们就数据合同达成了一致,但是这个过程很容易出错,而且我不断从服务器获取无效的数据对象。所以我的问题是我可以使用打字稿中定义的一些接口以某种方式验证动态对象(在运行时)吗?
这个问题是在 2012 年提出的,因此它不能与Check if an object 在运行时使用2015 年提出的TypeScript 实现接口重复。
我正在使用打字稿处理应用程序的 UI。与此同时,其他人也在努力为我提供数据。我们就数据合同达成了一致,但是这个过程很容易出错,而且我不断从服务器获取无效的数据对象。所以我的问题是我可以使用打字稿中定义的一些接口以某种方式验证动态对象(在运行时)吗?
这个问题是在 2012 年提出的,因此它不能与Check if an object 在运行时使用2015 年提出的TypeScript 实现接口重复。
就目前而言,TypeScript 接口是纯粹的编译时实体,因此无法进行任何类型的运行时验证,更不用说知道在编译时存在哪些接口。因此,答案似乎是以下之一:
您可以使用 JSON 模式作为运行时表示,因为 Github 上存在许多验证器。TypeScript 接口 --> JSON Schema 转换器是我希望有人在某个时候制作的东西,但据我所知,目前还不存在。
正如 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
一个新的复合界面。要在运行时验证给定类型是否满足 interface 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。