Below, I have a literal object {a:"a"}. I want to extract the value of the object as a literal "a", not its type string, so as to check if some other variables is "a" and not any other string.
However if I use mapped type I only get string, not "a".
Is there a way to get the value as a type?
const a = {a:"a"}
type trueIfLiteral<T extends string>= string extends T?false:true;
type key = keyof typeof a;
const t1 : trueIfLiteral<key> = true; // key is literal
type val = typeof a[key];
const t2 : trueIfLiteral<val> = false; // val is string
So the question is simply, how can I derive a type:
type valAsLiteral = "a"
First, to make the object slightly less confusing, let's call it
obj
with propertieskey
andval
:A problem here is that the object is typed as
{ key: string }
. TypeScript has automatically widened the'val'
from'val'
to a string. If you want to prevent that widening, you can declare the objectas const
:This results in your code working, and
produces
'val'
(andconst t2 : trueIfLiteral<val> = false; // val is string
fails, becauseval
is no longer a generic string, but onlyval
)To get the value in the emitted JS, not in TS, you can do
producing
'val'
, typed as'val'
, with no type widening.