5

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

porti20
  • 71
  • 1
  • 6
  • Does this answer your question? [Get type of generic parameter](https://stackoverflow.com/questions/18215899/get-type-of-generic-parameter) – bmtheo Jan 23 '20 at 07:17
  • Unfortunaly not, because the best solution requires an existing, defined value - which i didn't have. Is there a solution to dynamic create a defined primitive? – porti20 Jan 23 '20 at 07:21
  • I'm afraid not, this is what they explained in the linked answer : "Generics are a TypeScript concept that helps check the correctness of your code but doesn't exist in the compiled output. So the short answer is no, it's not possible." – bmtheo Jan 23 '20 at 07:40
  • types do not exist at runtime – Aleksey L. Jan 23 '20 at 07:48

2 Answers2

1

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));
porti20
  • 71
  • 1
  • 6
0

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.

Sintifo
  • 48
  • 7