class Foo<T> {
remake(){
return new Foo<T>;
}
recast(){
return this as any as Foo<Array<T>>
}
}
我要设置Foo
类的Child类。
子类应该在remake
和recast
上引用自己
另外,如果还有其他语法可以更改实例的泛型,对我也将很好。
答案 0 :(得分:2)
您可以使用remake
实现this.constructor
并使用this
类型键入它。 recast
需要higher-kinded types或一种伪造它们的方式,如下所示,并且需要您为每个子类显式指定类型构造函数(可以通过更高种类的本机实现自动推断出该类型构造函数类型)。
// Matt's mini "type functions" library
const INVARIANT_MARKER = Symbol();
type Invariant<T> = { [INVARIANT_MARKER](t: T): T };
interface TypeFuncs<C, X> {}
const FUN_MARKER = Symbol();
type Fun<K extends keyof TypeFuncs<{}, {}>, C> = Invariant<[typeof FUN_MARKER, K, C]>;
const BAD_APP_MARKER = Symbol();
type BadApp<F, X> = Invariant<[typeof BAD_APP_MARKER, F, X]>;
type App<F, X> = [F] extends [Fun<infer K, infer C>] ? TypeFuncs<C, X>[K] : BadApp<F, X>;
// Example
const F_Foo = Symbol();
type F_Foo = Fun<typeof F_Foo, never>;
const F_Bar = Symbol();
type F_Bar = Fun<typeof F_Bar, never>;
interface TypeFuncs<C, X> {
[F_Foo]: Foo<X>;
[F_Bar]: Bar<X>;
}
class Foo<T, F = F_Foo> {
remake(): this {
return new (<any>this.constructor)();
}
recast(): App<F, T[]> {
return this as any as App<F, T[]>;
}
}
class Bar<T, F = F_Bar> extends Foo<T, F> { }
let b = new Bar<number>();
let b2 = b.remake();
console.log(b2.constructor.name); // Bar
let b3 = b.recast(); // Bar<number[]>