TypeScript:继承类中静态方法的自引用返回类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34098023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript: self-referencing return type for static methods in inheriting classes
提问by Merott
With Polymorphic thisin TypeScript 1.7, as I discovered here, we can define a method in a class with a return type of this
, and automatically, any classes that extend that class and inherit the methods, will have their return types set to their respective this
type. Like so:
使用TypeScript 1.7 中的Polymorphic this,正如我在此处发现的,我们可以在返回类型为 的类中定义一个方法this
,并且自动地,扩展该类并继承这些方法的任何类都将其返回类型设置为各自的this
类型. 像这样:
class Model {
save():this { // return type: Model
// save the current instance and return it
}
}
class SomeModel extends Model {
// inherits the save() method - return type: SomeModel
}
However, what I'm after is to have an inherited static
method with a return type referencing the class itself. It's best described in code:
但是,我所追求的是拥有static
一个返回类型引用类本身的继承方法。最好在代码中描述:
class Model {
static getAll():Model[] {
// return all recorded instances of Model as an array
}
save():this {
// save the current instance and return it
}
}
class SomeModel extends Model {
// inherits the save() method - return type: SomeModel
// also inherits getAll() - return type: Model (how can we make that SomeModel?)
}
Perhaps I'll have to think of a different way to implement this, since Polymorphic this
in TypeScript 1.7 does not support static
methods by design.
也许我必须想出一种不同的方式来实现这一点,因为this
TypeScript 1.7 中的Polymorphic不支持设计static
方法。
EDIT: I guess we'll see how this Github issue wraps up: https://github.com/Microsoft/TypeScript/issues/5863
编辑:我想我们会看到这个 Github 问题是如何结束的:https: //github.com/Microsoft/TypeScript/issues/5863
回答by mrm
This is doable in TypeScript 2.0+. By using an inline { new(): T }
type to capture this
, you'll get what you wanted:
这在 TypeScript 2.0+ 中是可行的。通过使用内联{ new(): T }
类型来捕获this
,你会得到你想要的:
type Constructor<T> = { new (): T }
class BaseModel {
static getAll<T>(this: Constructor<T>): T[] {
return [] // dummy impl
}
/**
* Example of static method with an argument:
*/
static getById<T>(this: Constructor<T>, id: number): T | undefined {
return // dummy impl
}
save(): this {
return this // dummy impl
}
}
class SubModel extends BaseModel {}
const sub = new SubModel()
const savedSub: SubModel = sub.save()
// Behold: SubModel.getAll() returns SubModels, not BaseModel
const savedSubs: SubModel[] = SubModel.getAll()
Note that getAll
still expects no arguments with this typing.
请注意,getAll
这种类型仍然不需要参数。
For more information, see https://www.typescriptlang.org/docs/handbook/generics.html#using-class-types-in-genericsand https://stackoverflow.com/a/45262288/1268016
有关更多信息,请参阅https://www.typescriptlang.org/docs/handbook/generics.html#using-class-types-in-generics和https://stackoverflow.com/a/45262288/1268016
回答by Brian M. Hunt
Based on the simplest answerto the GitHub issue, you can use InstanceType<>
like this:
基于最简单的回答到GitHub的问题,你可以使用InstanceType<>
这样的:
class Foo {
static create<T extends typeof Foo>(this: T): InstanceType<T> {
return new this() as InstanceType<T>
}
static getAll<T extends typeof Foo>(this: T): Array<InstanceType<T>> {
return []
}
}
class Bar extends Foo { }
const a = Bar.getAll() // typeof a is Bar[]
const b = Bar.create() // typeof b is Bar.
Where I threw in the create
function just for illustration, from the linked GitHub example.
我create
从链接的 GitHub 示例中放入函数只是为了说明。
回答by Nypan
What are you expecting this static method to return in the inherited subclass? Is it something like this:
你期望这个静态方法在继承的子类中返回什么?是不是像这样:
class A {
private static _instances = new Array<A>();
static instances(): A[] { return A._instances; }
constructor() { A._instances.push(this); }
}
class B extends A {
static instances(): B[] {
return <B[]>(A.instances().filter(i => i instanceof B));
}
constructor() { super(); };
}
var a = new A();
var b = new B();
console.log(
"A count: " + A.instances().length +
" B count: " + B.instances().length);
This will output "A count: 2 B count: 1". Or what are you expecting?
这将输出“A 计数:2 B 计数:1”。或者你在期待什么?