Issue
I'm using a named type in my typescript file like so:
type VersionNumber =
| `${number}`
| `${number}.${number}`
| `${number}.${number}.${number}`
| `${number}.${number}.${number}.${string}`;
type Example = {
id:string
version:VersionNumber
}
let example:exmaple = {
id:'some.id',
version:['1.2'] // Type 'string[]' is not assignable to type 'VersionNumber'.
}
Type '
string[]
' is not assignable to type 'VersionNumber
'.
I find this very unhelpful because it doesn't even start to describe the definition of what VersionNumber
type is. The issue is that I find it very overwhelming to use the full type definition of VersionNumber
instead of the name. I could also endup reusing the type and that would mean duplicated code.
type Example = {
id:string
version:
| `${number}`
| `${number}.${number}`
| `${number}.${number}.${number}`
| `${number}.${number}.${number}.${string}`;
}
let example:exmaple = {
id:'some.id',
version:['1.2']
}
But that will change the error prompt to:
Type '
string[]
' is not assignable to type '${number}
|${number}.${number}
|${number}.${number}.${number}
|${number}.${number}.${number}.${string}
'.
Which is much more helpful to me.
Is there a way to always display the named type definition? I know that if the named type definition is simple, it will be displayed, but not with complex types with |
or complex objects.
Solution
Turns out you can, kind of.
I was using this DeepPartial type:
export type DeepPartial<T> = T extends object
? {
[P in keyof T]?: DeepPartial<T[P]>;
}
: T;
And I realised that if I looked at the DeepMerged type I would get a complete-ish picture of its "sub-types", so I simply removed the ?
used to make the values optional in the DeepPartial. It will cary the optional values as key: string | undefined
instead of key?: string
.
export type DeepCollapse<T> = T extends object
? {
[P in keyof T]: DeepCollapse<T[P]>;
}
: T;
What the type above does is turn any "sub-type" that is an object into a simple object, making its content visible to the parent level.
So for example, I could use types with names starting with _
to indicate they are private and export a DeepCollapse
type to help the user trying to use the module in typescript with a type error as detailed as possible.
Here's an example:
type VersionNumber = number[];
type _Example = {
id: string;
version: VersionNumber;
};
let example1: _Example = {
id: 'some.id',
version: '1.2', // Type 'string' is not assignable to type 'VersionNumber'.
};
type Example = DeepCollapse<_Example>;
let example2: Example = {
id: 'some.id',
version: '1.2', // Type 'string' is not assignable to type 'number[]'.
};
This is not a complete solution as it will not bring the type definition visible to the top level if it's a complex types with unions and template literals, only simple types like number[]
and such get to be visible at the parent level. If anyone has an idea of how to make those visible as well, that'd be great! Otherwise, they will have to refer to documentation for the extremeties of the types but at least they wont have to jump through many doucmentation hoops to view the full object structure of a config file.
Answered By - Samuel Charpentier
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.