在运行时针对 TypeScript 中的接口验证“任何”对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12868027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Validate 'any' object against an interface in TypeScript at runtime
提问by Trident D'Gao
I am working on the UI of an app using typescript. At the same time others work on providing me data. We agreed on the data contract however the process is error prone and I keep getting invalid data objects from the server. So my question is can I somehow validate dynamic objects (at run time) using some of my interfaces defined in typescript?
我正在使用打字稿处理应用程序的 UI。与此同时,其他人致力于为我提供数据。我们同意了数据合同,但是这个过程很容易出错,我不断从服务器获取无效的数据对象。所以我的问题是我可以使用我在 typescript 中定义的一些接口以某种方式验证动态对象(在运行时)吗?
This question was asked in 2012, thus it cannot be a duplicate of Check if an object implements an interface at runtime with TypeScriptasked in 2015.
这个问题是在 2012 年提出的,因此它不能与2015 年使用 TypeScript提出的检查对象是否在运行时实现接口重复。
回答by Brian Terlson
As it stands, TypeScript interfaces are purelycompile time entities so there is no way to do any sort of runtime validation let alone even knowing what interfaces existed at compile time. Thus, the answer would seem to be one of:
就目前而言,TypeScript 接口纯粹是编译时实体,因此无法进行任何类型的运行时验证,更不用说知道编译时存在哪些接口了。因此,答案似乎是以下之一:
- Write some tool to convert TypeScript interfaces to some runtime object representation that you can use to validate your objects, or:
- Duplicate your TypeScript interfaces as some runtime object representation
- 编写一些工具将 TypeScript 接口转换为一些运行时对象表示,您可以使用它来验证您的对象,或者:
- 复制你的 TypeScript 接口作为一些运行时对象表示
You could use JSON-schema as your runtime representation, as many validators exist on Github. A TypeScript interface --> JSON Schema converter is something I hope someone makes at some point, but as far as I'm aware doesn't exist as yet.
您可以使用 JSON-schema 作为您的运行时表示,因为 Github 上存在许多验证器。TypeScript 接口 --> JSON Schema 转换器是我希望有人在某个时候制作的东西,但据我所知,目前还不存在。
回答by Valentin
As Brian points out, interfaces manifest themselves only at compile time and are used as so-called named-typesby the compiler. Section 7 of the language specification describes this as follows:
正如 Brian 所指出的那样,接口仅在编译时显示自己,并被编译器用作所谓的命名类型。语言规范的第 7 节对此进行了如下描述:
Interfaces have no run-time representation—they are purely a compile-time construct. Interfaces are particularly useful for documenting and validating the required shape of properties, objects passed as parameters, and objects returned from functions.
接口没有运行时表示——它们纯粹是一个编译时构造。接口对于记录和验证所需的属性形状、作为参数传递的对象以及从函数返回的对象特别有用。
Further down in section 7.4 of the specthere is a nice description of dynamic type checks in Typescript:
在进一步向下规范的7.4节中有打字稿动态类型检查的一个很好的描述:
TypeScript does not provide a direct mechanism for dynamically testing whether an object implements a particular interface. Instead, TypeScript code can use the JavaScript technique of checking whether an appropriate set of members are present on the object...
TypeScript 不提供用于动态测试对象是否实现特定接口的直接机制。相反,TypeScript 代码可以使用 JavaScript 技术来检查对象上是否存在一组合适的成员......
The example in the specification defines three interfaces:
规范中的示例定义了三个接口:
interface Mover {
move(): void;
getStatus(): {speed: number;};
}
interface Shaker {
shake(): void;
getStatus(): {frequency: number;};
}
interface MoverShaker extends Mover, Shaker {
getStatus(): { speed: number; frequency: number; };
}
MoverShakercombines Moverand Shakerinto a new compound interface. To validate at runtimethat a given type fulfills interface MoverShaker, you can use Javascript code as follows:
MoverShaker联合机Mover和Shaker到一个新的化合物的界面。要在运行时验证给定类型满足 interface MoverShaker,您可以使用 Javascript 代码如下:
var obj: any = getSomeObject();
if (obj && obj.move && obj.shake && obj.getStatus) {
var moverShaker = <MoverShaker> obj;
...
}
In order to have compile-time checking in Typescript, you need to define interfaces for the types that are exchanged between the two parts of your application. Currently, you have to write dynamic checking code (as above) manually. Hence, static type and dynamic checking code may at some point deviate if you forget to update them in sync. As Brian points out, it would be nice to have a tool that generates the code automatically.
为了在 Typescript 中进行编译时检查,您需要为应用程序的两个部分之间交换的类型定义接口。目前,您必须手动编写动态检查代码(如上)。因此,如果您忘记同步更新,静态类型和动态检查代码可能会在某些时候偏离。正如布赖恩所指出的,拥有一个自动生成代码的工具会很好。
回答by Janus Troelsen
Try my dynamic interface checker if you like, here's an example (full example):
如果您愿意,请尝试我的动态界面检查器,这是一个示例(完整示例):
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;
}
When code equivalent to scratch({ intact: 42, color: Color.RED })is called, an error like this is thrown:
当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' ]
}
]
See the main page for instructions: https://github.com/ysangkok/typescript-interface-to-jsonschema
有关说明,请参阅主页:https: //github.com/ysangkok/typescript-interface-to-jsonschema
I'd add automatic typechecking, but I'd need something like node-falafelfor TypeScript.
我会添加自动类型检查,但我需要类似node-falafel的 TypeScript。

