0
class Foo<T> {
    remake(){
        return new Foo<T>;
    }
    recast(){
        return this as any as Foo<Array<T>>
    }
}

I want to make Child class of Foo Class. Child class should be referencing itself on remake and recast

also, If there has other syntax for change to generics of instance, it will be good to me.

1 Answer 1

2

You can implement remake using this.constructor and type it using the this type. recast needs higher-kinded types or a way of faking them, as below, and needs you to explicitly specify the type constructor for each subclass (it might be possible to infer this automatically with a native implementation of 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[]>
Sign up to request clarification or add additional context in comments.

4 Comments

Cool type acrobatics :)
I copied your codes, and change Invariant and TypeFuncs to interface, because of tslint. F_bar occurred error. TS2344: Type 'unique symbol' does not satisfy the constraint 'never'. I using 2.9.2
Can't use generic to this.constructor, need to other way like recast
Re first comment: Please add the exact code you tried to the question. Re second comment: I'm sorry, I don't understand what you mean at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.