我正在使用TypeScript中的一个接口来定义一个函数,该函数只在扩展基类的一些类上可用.这是我到目前为止的代码的简化版本:

class Animal {
}

interface IWalkingAnimal {
    walk(): void;
}

class Dog extends Animal implements IWalkingAnimal {
}

class Cat extends Animal implements IWalkingAnimal {
}

class Snake extends Animal {
}

private moveAnimal(animal: Animal) {
    if (animal instanceof Cat || animal instanceof Dog) {
        animal.walk();
    }
}

现在的问题是,我将添加更多的"行走"动物,这样moveAnimal功能将变得太大,无法管理.我想做的是这样的:

private moveAnimal(animal: Animal) {
    if (animal implements IWalkingAnimal ) {
        animal.walk();
    }
}

然而,"implements"判断不起作用,在使用接口时,我找不到与"instanceof"等效的选项.在Java中,"instanceof"的使用似乎可以在这里使用,但TypeScript不允许这样做.

TypeScript中存在这样的东西吗,或者这里有更好的方法吗?我使用的是打字脚本1.8.9.

推荐答案

与类不同,接口只在编译时存在,它们不包含在生成的JavaScript中,因此不能进行instanceof次判断.

你可以将IWalkingAnimal作为Animal的一个子类(使用instanceof),或者你可以判断所讨论的对象是否有walk方法:

if (animal['walk']) {}

您可以将其包装为user defined type guard(这样,当在if语句中使用时,编译器可以缩小类型,就像instanceof一样).

/**
* User Defined Type Guard!
*/
function canWalk(arg: Animal): arg is IWalkingAnimal {
   return (arg as IWalkingAnimal).walk !== undefined;
}


private moveAnimal(animal: Animal) {
    if (canWalk(animal)) {
        animal.walk();  // compiler knows it can walk now
    }
}

Typescript相关问答推荐

如何将函数类型应用到生成器?

如何正确修复TypScript 4.7到4.8升级中的TS 2345编译错误

为什么ESLint抱怨通用对象类型?

在将对象从一个对象转换成另一个对象时,可以缩小对象的键吗?

根据另一个属性的值来推断属性的类型

在嵌套属性中使用Required

如何在TypeScript中将一个元组映射(转换)到另一个元组?

类型脚本满足将布尔类型转换为文字.这正常吗?

路由链接始终返回到

Angular 17子路由

有没有可能产生输出T,它在视觉上省略了T中的一些键?

如何在Typescript 中组合unions ?

为什么Typescript只在调用方提供显式泛型类型参数时推断此函数的返回类型?

为什么TypeScrip不能解析对象析构中的赋值?

界面中数组中的混合类型导致打字错误

创建一个函数,该函数返回一个行为方式与传入函数相同的函数

Typescript .根据枚举输入参数返回不同的对象类型

Vite+Chrome扩展 list v3-;不能在模块外使用import语句;对于inpage脚本

React Context TypeScript错误:属性';firstName';在类型';iCards|iSearch';

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数