typescripttypescript-typingstypescript-generics

How to replace a generic type in a custom generic type


class X<T> {
    _t: T|null = null
}

class Y<T> {
    _y: T|null = null
}

type ReplaceT<V extends unknown<any>, NewT> = unknown // How to do this

const x = new X<string>
const y = new Y<string>

// Assume that `x` is a type with 1 generic

type T1 = ReplaceT<typeof x, number> // X<number> expected
type T2 = ReplaceT<typeof x, boolean> // X<boolean> expected
type T3 = ReplaceT<typeof y, boolean> // Y<boolean> expected

Playground

Is this possible?


Solution

  • You can use conditional types if V is either X or Y:

    class X<T> {
        _t: T|null = null
    }
    
    class Y<T> {
        _y: T|null = null
    }
    
    type ReplaceT<V extends X<any> | Y<any>, NewT extends any> =
        V extends X<any> 
        ? X<NewT>
        : V extends Y<any>
            ? Y<NewT>
            : never;
    
    const x = new X<string>
    const y = new Y<string>
    
    // Assume that `x` is a type with 1 generic
    
    type T1 = ReplaceT<typeof x, number> // X<number> expected
    type T2 = ReplaceT<typeof x, boolean> // X<boolean> expected
    type T3 = ReplaceT<typeof y, boolean> // Y<boolean> expected