Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Typescript检查接口类型_Javascript_Typescript_Interface - Fatal编程技术网

Javascript 使用Typescript检查接口类型

Javascript 使用Typescript检查接口类型,javascript,typescript,interface,Javascript,Typescript,Interface,这个问题是与这个问题的直接类比 我需要在运行时查明任何类型的变量是否实现了接口。这是我的密码: interface A{ member:string; } var a:any={member:"foobar"}; if(a instanceof A) alert(a.member); 如果在typescript中输入此代码,最后一行将标记为错误,“名称A在当前范围内不存在”。但事实并非如此,该名称确实存在于当前范围中。我甚至可以将变量声明更改为vara:a={member:“foo

这个问题是与这个问题的直接类比

我需要在运行时查明任何类型的变量是否实现了接口。这是我的密码:

interface A{
    member:string;
}

var a:any={member:"foobar"};

if(a instanceof A) alert(a.member);
如果在typescript中输入此代码,最后一行将标记为错误,“名称A在当前范围内不存在”。但事实并非如此,该名称确实存在于当前范围中。我甚至可以将变量声明更改为
vara:a={member:“foobar”}编辑没有抱怨。在浏览网页并找到另一个问题后,我将接口更改为类,但随后我无法使用对象文本创建实例

我想知道A类型怎么会像那样消失,但看看生成的javascript就可以解释问题了:

var a = {
    member: "foobar"
};
if(a instanceof A) {
    alert(a.member);
}
没有接口的表示形式,因此不可能进行运行时类型检查

我知道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);
}

您无需使用
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);
}

我想指出,TypeScript并没有提供直接的机制来动态测试对象是否实现了特定的接口

相反,TypeScript代码可以使用JavaScript技术检查对象上是否存在一组适当的成员。例如:

var obj : any = new Foo();

if (obj.someInterfaceMethod) {
    ...
}
function foo (arg: number | string) {
    if (typeof arg === 'number') {
        // fine, type number has toFixed method
        arg.toFixed()
    } else {
        // Property 'toFixed' does not exist on type 'string'. Did you mean 'fixed'?
        arg.toFixed()
        // TSC can infer that the type is string because 
        // the possibility of type number is eliminated at the if statement
    }
}
interface Dog {
    bark: () => void;
}

// The function isDog is a user defined type guard
// the return type: 'pet is Dog' is a type predicate, 
// it determines whether the object is a Dog
function isDog(pet: object): pet is Dog {
  return (pet as Dog).bark !== undefined;
}

const dog: any = {bark: () => {console.log('woof')}};

if (isDog(dog)) {
    // TS now knows that objects within this if statement are always type Dog
    // This is because the type guard isDog narrowed down the type to Dog
    dog.bark();
}

我想指出,TypeScript并没有提供直接的机制来动态测试对象是否实现了特定的接口

相反,TypeScript代码可以使用JavaScript技术检查对象上是否存在一组适当的成员。例如:

var obj : any = new Foo();

if (obj.someInterfaceMethod) {
    ...
}
function foo (arg: number | string) {
    if (typeof arg === 'number') {
        // fine, type number has toFixed method
        arg.toFixed()
    } else {
        // Property 'toFixed' does not exist on type 'string'. Did you mean 'fixed'?
        arg.toFixed()
        // TSC can infer that the type is string because 
        // the possibility of type number is eliminated at the if statement
    }
}
interface Dog {
    bark: () => void;
}

// The function isDog is a user defined type guard
// the return type: 'pet is Dog' is a type predicate, 
// it determines whether the object is a Dog
function isDog(pet: object): pet is Dog {
  return (pet as Dog).bark !== undefined;
}

const dog: any = {bark: () => {console.log('woof')}};

if (isDog(dog)) {
    // TS now knows that objects within this if statement are always type Dog
    // This is because the type guard isDog narrowed down the type to Dog
    dog.bark();
}

现在可以了,我刚刚发布了一个增强版的
TypeScript
编译器,它提供了全反射功能。您可以从类的元数据对象实例化类,从类构造函数检索元数据,并在运行时检查接口/类。你可以去看看

用法示例:

在其中一个typescript文件中,创建一个接口和一个实现该接口的类,如下所示:

interface MyInterface {
    doSomething(what: string): number;
}

class MyClass implements MyInterface {
    counter = 0;

    doSomething(what: string): number {
        console.log('Doing ' + what);
        return this.counter++;
    }
}
现在,让我们打印一些已实现接口的列表

for (let classInterface of MyClass.getClass().implements) {
    console.log('Implemented interface: ' + classInterface.name)
}
使用reflec ts编译并启动它:

$ node main.js
Implemented interface: MyInterface
Member name: counter - member kind: number
Member name: doSomething - member kind: function
参见reflection.d.ts了解
接口
元类型详细信息

更新:
您可以找到一个完整的工作示例

现在可以了,我刚刚发布了一个增强版的
TypeScript
编译器,它提供了全反射功能。您可以从类的元数据对象实例化类,从类构造函数检索元数据,并在运行时检查接口/类。你可以去看看

用法示例:

在其中一个typescript文件中,创建一个接口和一个实现该接口的类,如下所示:

interface MyInterface {
    doSomething(what: string): number;
}

class MyClass implements MyInterface {
    counter = 0;

    doSomething(what: string): number {
        console.log('Doing ' + what);
        return this.counter++;
    }
}
现在,让我们打印一些已实现接口的列表

for (let classInterface of MyClass.getClass().implements) {
    console.log('Implemented interface: ' + classInterface.name)
}
使用reflec ts编译并启动它:

$ node main.js
Implemented interface: MyInterface
Member name: counter - member kind: number
Member name: doSomething - member kind: function
参见reflection.d.ts了解
接口
元类型详细信息

更新: 您可以在TypeScript 1.6中找到一个完整的工作示例,它将完成这项工作

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;
}
它也可以与
开关一起工作。

在TypeScript 1.6中,将完成这项工作

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;
}

它也可以与
开关一起工作。

typescript 2.0


typescript 2.0引入带标记的联合


用户定义的类型保护怎么样

接口鸟{
苍蝇();
layEggs();
}
界面鱼{
游泳();
layEggs();
}
函数是鱼(宠物:鱼|鸟):宠物是鱼{//魔法发生在这里
返回(宠物)。游泳!==未定义;
}
//现在“游泳”和“飞”都可以了。
如果(鱼(宠物)){
宠物游泳;
}
否则{
pet.fly();
}

用户定义的类型防护怎么样

接口鸟{
苍蝇();
layEggs();
}
界面鱼{
游泳();
layEggs();
}
函数是鱼(宠物:鱼|鸟):宠物是鱼{//魔法发生在这里
返回(宠物)。游泳!==未定义;
}
//现在“游泳”和“飞”都可以了。
如果(鱼(宠物)){
宠物游泳;
}
否则{
pet.fly();
}
打字保护装置

interface MyInterfaced {
    x: number
}

function isMyInterfaced(arg: any): arg is MyInterfaced {
    return arg.x !== undefined;
}

if (isMyInterfaced(obj)) {
    (obj as MyInterfaced ).x;
}
打字机

interface MyInterfaced {
    x: number
}

function isMyInterfaced(arg: any): arg is MyInterfaced {
    return arg.x !== undefined;
}

if (isMyInterfaced(obj)) {
    (obj as MyInterfaced ).x;
}

这里还有另一个选项:模块提供了一个构建时工具,可以将TypeScript接口转换为运行时描述符,并可以检查对象是否满足它

以OP为例,

首先运行
ts interface builder
,它会生成一个新的简明文件,其中包含一个描述符,例如
foo ti.ts
,您可以这样使用它:

从“/foo ti.ts”导入fooDesc;
从“ts接口检查器”导入{createCheckers};
const{A}=createCheckers(fooDesc);
检查({成员:“你好”});//好啊
检查({成员:17});//因“.成员不是字符串”而失败
你可以创造
declare const isCompositeFilterDescriptor: (source: FilterDescriptor | CompositeFilterDescriptor) => source is CompositeFilterDescriptor;
const filters: Array<FilterDescriptor | CompositeFilterDescriptor> = filter.filters;

filters.forEach((element: FilterDescriptor | CompositeFilterDescriptor) => {
    if (isCompositeFilterDescriptor(element)) {
        // element type is CompositeFilterDescriptor
    } else {
        // element type is FilterDescriptor
    }
});
function foo (arg: number | string) {
    if (typeof arg === 'number') {
        // fine, type number has toFixed method
        arg.toFixed()
    } else {
        // Property 'toFixed' does not exist on type 'string'. Did you mean 'fixed'?
        arg.toFixed()
        // TSC can infer that the type is string because 
        // the possibility of type number is eliminated at the if statement
    }
}
interface Dog {
    bark: () => void;
}

// The function isDog is a user defined type guard
// the return type: 'pet is Dog' is a type predicate, 
// it determines whether the object is a Dog
function isDog(pet: object): pet is Dog {
  return (pet as Dog).bark !== undefined;
}

const dog: any = {bark: () => {console.log('woof')}};

if (isDog(dog)) {
    // TS now knows that objects within this if statement are always type Dog
    // This is because the type guard isDog narrowed down the type to Dog
    dog.bark();
}
// Notice there is no naming conflict, because interfaces are a *type*
export const IAnimal = Symbol("IAnimal"); 
export interface IAnimal {
  [IAnimal]: boolean; // the fubber
}

export const IDog = Symbol("IDog");
export interface IDog extends IAnimal {
  [IDog]: boolean;
}

export const IHound = Symbol("IDog");
export interface IHound extends IDog {
  // The fubber can also be typed as only 'true'; meaning it can't be disabled.
  [IDog]: true;
  [IHound]: boolean;
}
import { IDog, IAnimal } from './interfaces';
class Dog implements IDog {
  // Multiple fubbers to handle inheritance:
  [IAnimal] = true;
  [IDog] = true;
}

class Hound extends Dog implements IHound {
  [IHound] = true;
}
import { IDog, IAnimal } from './interfaces';

let dog = new Dog();

if (dog instanceof Hound || dog[IHound]) {
  // false
}
if (dog[IAnimal]?) {
  // true
}

let houndDog = new Hound();

if (houndDog[IDog]) {
  // true
}

if (dog[IDog]?) {
  // it definitely is a dog
}