TypeScript中静态方法的抽象方法版本

时间:2016-09-25 18:09:53

标签: generics inheritance typescript abstract-class

我正在使用typescript创建数据模型范例。我在不同的地方存储不同类型的数据(SQL,本地缓存)。我想创建一个抽象类,其中包含我需要的任何类型的数据存储(创建,查找,更新,计数,销毁)所需的所有方法。这样我就可以扩展该类并以不同的方式为不同类型的存储实现它,如果我错过了一个方法,编译器会警告我。然后,我将在描述数据模型的类中扩展其中一个实现。但是,我需要的一些方法(例如查找和创建)是静态的。我知道typescript不支持抽象静态方法。是否有类似于我可以使用的抽象方法的东西,所以编译器警告我缺少方法?

我还希望这些静态方法是通用的,并且类型与类相同。我知道这对标准泛型类没有意义。但是,由于此类将始终被扩展并且从未实例化,我可以在扩展它时键入泛型类,自动更新静态方法上的泛型类型吗?

2 个答案:

答案 0 :(得分:2)

  

是否有类似于我可以使用的抽象方法的东西,所以编译器警告我缺少方法

没有内置,因此只需

就不会出现错误
// WILL NOT COMPILE. SAMPLE
class Foo {
    abstract static X() { } 
}

class Bar extends Foo { // Error here please
}

但是,您可以使用类型兼容性等技巧来确保:

interface FooAbstract {
    X(): any;
}
let _ensureAbstractMatch: FooAbstract;
class Foo {
}

class Bar extends Foo {
}
_ensureAbstractMatch = Bar; // Error missing method

示例实施:

interface FooAbstract {
    X(): any;
}
let _ensureAbstractMatch: FooAbstract;
class Foo {
}

class Bar extends Foo {
    static X() { }
}
_ensureAbstractMatch = Bar; // OKAY

答案 1 :(得分:0)

<块引用>

我知道打字稿不支持抽象静态方法。有没有类似于我可以使用的 [静态] 抽象方法的东西......?

也在研究抽象静态。答案是 abstract static 声明是 not yet supported,但您可以做一些接近的事情:要求 class object 实现抽象类,这相当于说它的静态必须实现接口。以我从其他几个答案中学到的一些部分为例123

// The static interface.
abstract class ResourceContainer { 
  abstract create(resource: Creator): Resource
  abstract count(query?: Query): number
  abstract find(query: Query): FindResult
}
// The instance interface.
abstract class Resource { 
  abstract read(): ReadResult
  abstract update(resource: Updator): ReadResult
  abstract delete(): void
}
// Attach newable to type corresponding to a concrete class - because Typescript ...
type NewableResource = ({new (...args: any): any} & ResourceContainer) 

const FooResource: NewableResource = class extends Resource {
  static create(resource: Creator): Resource { console.debug('create'); return new this(); }
  static find(query?: Query) { console.debug('find'); }
  static count(query?: Query) { console.debug('count'); return 0; }
  read() { console.debug('read'); }
  update(resource: Updator) { console.debug('update'); }
  delete() { console.debug('delete'); }
}

// TODO: flesh out these utility types ..
type Query = unknown;
type FindResult = unknown;
type ReadResult = unknown;
type Updator = unknown;
type Creator = unknown;

// Get the *type* of an class object *value*.
type FooResource = InstanceType<typeof FooResource> 

const x: FooResource = FooResource.create({});
x.read()

或者,如果您愿意,您可以这样做:

abstract class Resource {
  static create(resource: Creator): Resource { throw NotImplementedError() }
  static count(query?: Query): number { throw NotImplementedError() }
  static find(query: Query): FindResult { throw NotImplementedError() }
  abstract read(): ReadResult
  abstract update(resource: Updator): ReadResult
  abstract delete(): void
}