I have the following generic function:
type Identity = <T extends string | number>(arg: T) => T;
const identity: Identity = (x) => x;
If I attempt to use this function like so, I get errors that I cannot reassign.
let a = identity('a');
a = 'b'; // Error: Type '"b"' is not assignable to type '"a"'
let b = identity(1);
b = 2; // Error: Type '2' is not assignable to type '1'
I would expect the type returned from identity to be either a string or number, however it seems I am getting literal types back of 'a' and 1. Why is this the case? and is there a way to change my constraints so this is the behaviour?
I've have found a couple of workarounds. Firstly to assign the parameter to a variable first:
let a_param = 'a'
let a = identity(a_param);
a = 'b'; // Yay
let b_param = 1;
let b = identity(b_param);
b = 2; // Yay
And secondly to cast to a string or number:
let a = identity('a' as string);
a = 'b'; // Yay
let b = identity(1 as number);
b = 2; // Yay
Both of these feel wrong. I'm still learning TS so I think I've missed something.