这个问题直接类似于TypeScript中的类类型检查
我需要在运行时找出任何类型的变量是否实现了接口。这是我的代码:
interface A{
member:string;
}
var a:any={member:"foobar"};
if(a instanceof A) alert(a.member);
如果您在typescript游乐场中输入这段代码,最后一行将被标记为错误,“名称A不存在于当前作用域”。但事实并非如此,该名称确实存在于当前作用域中。我甚至可以更改变量声明为var a: a ={成员:"foobar"};没有编辑的抱怨。在浏览网页并找到其他问题后,我将接口更改为类,但我不能使用对象字面量来创建实例。
我想知道A类型是如何消失的,但看看生成的javascript就能解释这个问题:
var a = {
member: "foobar"
};
if(a instanceof A) {
alert(a.member);
}
没有将A表示为接口,因此不可能进行运行时类型检查。
我知道javascript作为一种动态语言没有接口的概念。是否有方法对接口进行类型检查?
typescript游乐场的自动完成显示typescript甚至提供了一个方法实现。我怎么使用它?
你可以在没有instanceof关键字的情况下实现你想要的,因为你现在可以编写自定义类型保护:
interface A {
member: string;
}
function instanceOfA(object: any): object is A {
return 'member' in object;
}
var a: any = {member: "foobar"};
if (instanceOfA(a)) {
alert(a.member);
}
会员众多
如果需要检查大量成员以确定对象是否与您的类型匹配,则可以添加标识符。下面是最基本的示例,并要求您管理自己的鉴别器…您需要深入了解模式,以确保避免重复标识符。
interface A {
discriminator: 'I-AM-A';
member: string;
}
function instanceOfA(object: any): object is A {
return object.discriminator === 'I-AM-A';
}
var a: any = {discriminator: 'I-AM-A', member: "foobar"};
if (instanceOfA(a)) {
alert(a.member);
}
我知道我偶然发现了一个github包,它正确地解决了这个问题,在我的搜索历史中,我终于找到了它。检查typescript-is -尽管它要求你的代码使用ttypescript编译(我目前正在强迫它与create-react-app一起工作,稍后将在成功/失败时更新),你可以用它做各种疯狂的事情。与ts-validate-type不同,这个包也是主动维护的。
你可以检查某个东西是否是字符串或数字,并将其作为字符串或数字使用,而编译器不会抱怨:
import { is } from 'typescript-is';
const wildString: any = 'a string, but nobody knows at compile time, because it is cast to `any`';
if (is<string>(wildString)) { // returns true
// wildString can be used as string!
} else {
// never gets to this branch
}
if (is<number>(wildString)) { // returns false
// never gets to this branch
} else {
// Now you know that wildString is not a number!
}
你也可以检查你自己的接口:
import { is } from 'typescript-is';
interface MyInterface {
someObject: string;
without: string;
}
const foreignObject: any = { someObject: 'obtained from the wild', without: 'type safety' };
if (is<MyInterface>(foreignObject)) { // returns true
const someObject = foreignObject.someObject; // type: string
const without = foreignObject.without; // type: string
}
这里还有另一个选项:模块ts-interface-builder提供了一个构建时工具,可以将TypeScript接口转换为运行时描述符,ts-interface-checker可以检查对象是否满足它。
对于OP的例子,
interface A {
member: string;
}
首先运行ts-interface-builder,它会生成一个带有描述符(比如foo-ti)的新简洁文件。Ts,你可以这样用:
import fooDesc from './foo-ti.ts';
import {createCheckers} from "ts-interface-checker";
const {A} = createCheckers(fooDesc);
A.check({member: "hello"}); // OK
A.check({member: 17}); // Fails with ".member is not a string"
你可以创建一个单行类型保护函数:
function isA(value: any): value is A { return A.test(value); }