[英]How to define a Typescript type that will only accept instances of some user defined class
我正在编写一个简单的ECS库,并希望强制我的用户提供他们正在定义的系统的名称。 我想在错误/调试消息中使用它。 同时,我不想强迫他们将每个系统都实现为 class。
我想要实现的是允许用户提供具有“名称”属性的 object 文字,或提供 class 的实例。 在后一种情况下,我不需要名称,因为console.log(instance)
的描述性就足够了。 如:
class MyStatefulSystem implements System {
run(...) {...}
}
createEngine().defineSystem(new MyStatefulSystem());
createEngine().defineSystem({name: "simple system", run: (...)=> {}})
如何定义仅匹配任何 class 实例的类型? 我已经有了一些简化,是:
export interface System {
run: (...) => void;
}
interface ExplicitlyNamedSystem extends System {
name: string;
}
type SystemClass = ?
export type NamedSystem =
| ExplicitlyNamedSystem
| SystemClass;
我将创建SystemClass
和抽象 class ,在构造函数中定义名称。
export interface System {
run: () => void;
}
interface ExplicitlyNamedSystem extends System {
name: string;
}
abstract class SystemClass implements ExplicitlyNamedSystem {
public readonly name: string;
constructor() {
this.name = this.constructor.name;
}
abstract run: () => void;
}
type NamedSystem = ExplicitlyNamedSystem | SystemClass;
const defineSystem = (s: NamedSystem) => {
console.log('Going to run NamedSystem', s.name);
s.run();
}
export {
defineSystem.
SystemClass
}
import { defineSystem, SystemClass } from 'systemstuff';
class UserDefined extends SystemClass {
public readonly run = () => {
console.log('inside running!');
}
}
defineSystem(new UserDefined());
defineSystem({name: 'bob', run: () => console.log('literal')});
TypeScript 不区分 class 实例和普通的 JavaScript 对象。 无法创建您正在寻找的工会。
我的建议是要求两者都提供name
。
interface System {
readonly name: string;
run(): void;
}
class System implements System {
constructor(readonly name: string) { }
run() {}
}
这两种方法都将创建一个System
object:
const instance = new System('my-system');
const object: System = {
name: 'my-system',
run() {}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.