porti20
porti20

Reputation: 81

Typescript: get type of generic type

I'm new to Typescript (come from C#) and i'm struggeling with the "special" generic implementation.

Here is my code:

function createValue<TValue extends string | boolean>(): TValue[]
{
    let result = new Array<TValue>();

    if (typeof TValue === "string") // error 'TValue' only refers to a type, but is being used as a value here
    {
        result[0] = "abc" as TValue;
    }
    else
    {
        result[0] = false as TValue;
    }

    return result;
}

console.log(createValue<boolean>());

How did i get the type?

I'm allready tried pretty ugly solutions to create a value, but this also don't behave as expected.

let value : TValue = new Array<TValue>(1)[0];
let type = typeof value; // undefined

There exists several solutions for object types but i didn't get it for primitives.

Could you give me any help?

Thanks

Upvotes: 6

Views: 14761

Answers (2)

porti20
porti20

Reputation: 81

Because Types did not exists at runtime i end up with a solution like this:

enum Types
{
    string,
    boolean,
    number
}

function getType<TValue extends Types.string | Types.boolean>(t: TValue): Array<TValue extends Types.string ? string : boolean>
{
    if (<Types>t == Types.string)
    {
        let arr = new Array<string>();
        arr[0] = "abcd";
        return arr as Array<TValue extends Types.string ? string : boolean>;       
    }

    let arr = new Array<boolean>();
    arr[0] = false;
    return arr as Array<TValue extends Types.string ? string : boolean>;     
}

console.log(getType(Types.boolean));

Upvotes: 1

Sintifo
Sintifo

Reputation: 58

Your problem lies in using the TypeScript type at runtime. TypeScript is compiled to JavaScript, therefore your execution does not see the the type TValue at all.

The typeof operator is used to reuse type information at other places but not at runtime. E.g.

function test(arg: string): boolean;

function test2(func1: typeof test): boolean;

Depending on what you want to achieve, you need to give a string argument that specifies your operation.

function createValue(type: 'string' | 'boolean') {
    let result = new Array();

    if (type === "string") 
    {
        result[0] = "abc";
    }
    else
    {
        result[0] = false;
    }

    return result;
}

console.log(createValue('boolean'));

TypeScript should be able to infer your types from there. If not, you could look into conditional types.

Upvotes: 0

Related Questions