The Typescript compiler will infer a string literal type for consts:
const a = 'abc';
const b: 'abc' = a; // okay, a is of type 'abc' rather than string
However, for properties, the type is inferred to be string
.
const x = {
y: 'def',
};
const z: { y: 'def' } = x; // error because x.y is of type string
In this example, how can I get the compiler to infer that x
is of type { y: 'def' }
without writing a type annotation for x
?
Edit: There's an open issue requesting support for this feature. One suggested workaround is to use syntax like this:
const x = new class {
readonly y: 'def';
};
const z: { readonly y: 'def' } = x; // Works
Try it in Playground here.
Edit 2: There's even an open PR that would solve this problem. Disabling type widening seems to be a popular request.
Using infer in TypeScript It does that by first checking whether your type argument ( T ) is a function, and in the process of checking, the return type is made into a variable, infer R , and returned if the check succeeds: type ReturnType<T> = T extends (... args: any[]) => infer R ?
The string literal type allows you to specify a set of possible string values for a variable, only those string values can be assigned to a variable. TypeScript throws a compile-time error if one tries to assign a value to the variable that isn't defined by the string literal type.
In Typescript, Type assertion is a technique that informs the compiler about the type of a variable. Type assertion is similar to typecasting but it doesn't reconstruct code. You can use type assertion to specify a value's type and tell the compiler not to deduce it.
I think you're looking for the const assertion, added in TS 3.4.
You just need to add as const
to the string for it to become a literal type.
const x = {
y: 'def' as const,
};
const z: { y: 'def' } = x; // no error :)
TS playground link
The difference is there is no const
keyword for properties. Since there is no way to be sure the properties won't be mutated TS cannot assume a constant string literal, it has to assume the more generic string
.
Try replacing the first const
in your example with let
and at that location too TS is going to assume string
and not 'abc'
:
let a = 'abc';
const b: 'abc' = a;
TS Playground link for this code
Is going to show an error for b
"Type string is not assignable to type 'abc'".
Since TS cannot infer immutability from a language feature, as you do in your const
variables example, the only way is to tell it that the obejct property is immutable is via an explicit type annotation, meaning the answer to your question is a negative.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With