这个问题是Class type check with TypeScript的直接类比。
我需要在运行时找出any类型的变量是否实现了接口。下面是我的代码:
interface A{
member:string;
}
var a:any={member:"foobar"};
if(a instanceof A) alert(a.member);
如果您在typescript操场中输入此代码,最后一行将被标记为错误,“名称A不存在于当前作用域中”。但事实并非如此,该名称确实存在于当前作用域中。我甚至可以将变量声明更改为var a:A={member:"foobar"};
,而不会收到编辑器的抱怨。在浏览网页并找到另一个问题后,我将接口更改为一个类,但之后我不能使用对象字面量来创建实例。
我想知道类型A怎么会像这样消失,但看看生成的javascript就能解释这个问题:
var a = {
member: "foobar"
};
if(a instanceof A) {
alert(a.member);
}
没有将A表示为接口,因此不可能进行运行时类型检查。
我知道javascript作为一种动态语言没有接口的概念。有没有办法检查接口的类型?
typescript playground的自动完成功能显示,typescript甚至提供了一种implements
方法。我怎么使用它?
发布于 2013-01-20 23:57:08
您可以在没有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);
}
发布于 2015-11-16 18:35:45
在TypeScript 1.6中,user-defined type guard将完成这项工作。
interface Foo {
fooProperty: string;
}
interface Bar {
barProperty: string;
}
function isFoo(object: any): object is Foo {
return 'fooProperty' in object;
}
let object: Foo | Bar;
if (isFoo(object)) {
// `object` has type `Foo`.
object.fooProperty;
} else {
// `object` has type `Bar`.
object.barProperty;
}
正如Joe Yang提到的:从TypeScript 2.0开始,您甚至可以利用标记联合类型的优势。
interface Foo {
type: 'foo';
fooProperty: string;
}
interface Bar {
type: 'bar';
barProperty: number;
}
let object: Foo | Bar;
// You will see errors if `strictNullChecks` is enabled.
if (object.type === 'foo') {
// object has type `Foo`.
object.fooProperty;
} else {
// object has type `Bar`.
object.barProperty;
}
它也适用于switch
。
发布于 2016-07-13 17:51:44
typescript 2.0引入带标记的联合
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Rectangle | Circle;
function area(s: Shape) {
// In the following switch statement, the type of s is narrowed in each case clause
// according to the value of the discriminant property, thus allowing the other properties
// of that variant to be accessed without a type assertion.
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.width * s.height;
case "circle": return Math.PI * s.radius * s.radius;
}
}
https://stackoverflow.com/questions/14425568
复制相似问题