The first type:
declare type roles = 'admin' | 'user';
The other type
declare type ROLES = 'ADMIN' | 'USER';
I need to assign from the first to the second, this is my current code:
const r: roles = 'admin';
const R: ROLES = r.toUpperCase() as ROLES;
But I don't want to explicitly cast, is there any better workaround without enforcing the cast?
EDIT: The solution I went with:
const r: roles = 'admin';
const R: ROLES = r.toUpperCase() as Uppercase<roles>;
With this approach, if later a new value added to roles
but not ROLES
, TS will complain about the mismatch.
CodePudding user response:
Sadly, a cast is required somewhere. The built in toUpperCase()
method returns the type string
, even when you call it on a string literal value. So the type of the string literal you started with is lost when this is called.
You could pass the cast down the line a bit and make a generic function:
function toUpperCase<T extends string>(str: T): Uppercase<T> {
return str.toUpperCase() as Uppercase<T>
}
const r: roles = 'admin';
const R: ROLES = toUpperCase(r); // works
But the cast is still required here for the same reason. But at least now the cast is not hardcoding your data model.
Whether this solution is an improvement over the as ROLES
case is a matter of opinion.