-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tooltips / IntelliSense: Don't resolve type aliases (aka "semantic sugar") set explicitly #31940
Comments
From the documentation: https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases
So it seems to be intentional, tho I personally would hope for a change regarding this as well. |
It is NOT a new type of course, it's just an alias - I mean: That's the whole point of an alias. Nonetheless nothing contradicts showing the alias in tooltips (or both - c.f. Alternative in my OP) IMHO.
These two sentences are contradicting another, aren't they? |
Given: // ./provider.ts
export type DOMFile = File; // ./consumer.ts
import { DOMFile } from './provider';
type File = {
id: string;
file: DOMFile;
}; Hover over type File = {
id: string;
file: File;
}; The type inspection shows This issue does not apply if we use interfaces: // ./provider.ts
export interface DOMFile extends File {} Is there a reason for type aliases to have different behaviour to interfaces in this context? |
I have also found, repeatedly, that it would be far more useful to simply show the developer the name of the type being referenced in intellisense, rather than trying to resolve the type definition. Actually, it would be useful. Fullstop. Since descriptions in intellisense like this, really aren't:
If it kept the type name, I could actually go to the type, read its documentation etc. and better understand the intent. Understand that type aliases are 'just aliases'... but this is really just about creating a better developer experience. Personally, I never really understood why there needed to be separate 'type' and 'interface' entities. |
OMG!! I've never seen the correlation to my feature request until now!! Yes, I fully second this. Error messages would be far more readable if |
+1 for this. In our project, I wanted to declare some semantic types representing numbers, to remove some of the ambiguity of "what does this random float value actually mean?", so I added these type alias declarations: type percentage = number
type timeInSeconds = number
type timeInMilliseconds = number
type radians = number
type degrees = number
type gameUnits = number I was quite disappointed to see that the assorted tooltips/intellisense did not keep the alias in tact, and just resolved down to a |
I just stumbled across this behavior as well and would like to see the recommended change. Having type aliases can make code clearer and easier to read. But when this information gets erased in the tooltip, it looses its purpose. |
+1 It gets even worse with generic functions. For rich type modelling, type hints like this: (methode) toResult<Readonly<{
searchIndexId: string;
searchResult: Readonly<{
pageInfo: Readonly<{
pageIndex: number;
totalNumPages: number;
numItemsOnThisPage: number;
numItemsPerPage: number;
totalNumItems: number;
}>;
pageData: readonly Readonly<...>[];
}>;
}>>(response: ServerResponse<...>): Result<...> are almost useless. I can't even see the function parameter's full type, because all the space is used up for the generic type description. (methode) toResult<SearchForProjects>(response: ServerResponse<SearchForProjects>): Result<string, SearchForProjects> honoring my type aliases. |
Faced same issue when wanted to short function foo<
T1 extends Dict,
T2 extends Dict,
T3 extends Dict,
T4 extends Dict
>(
param1: T1,
param2: T2,
param3: T3
): T4 Showed in tooltip as: function foo<T1 extends Record<string, unknown>, T2 extends Record<string, unknown>, T3 extends Record<string, unknown>, T4 extends Record<string, unknown>>(param1: T1, param2: T2, param3: T3): T4 I was very frustrated when faced this problem! Please fix this or at least add setting to change this behavior! Definitions are just unreadable! |
+100 for this! Just wondering if there's been any progress? In my mind there's no obvious drawback for this. When working with complex types, it quickly makes the tooltip obscure and hard to understand the error. At the very least, an option to show alias instead of resolving should be enough. Just to extra emphasise this, consider the following, in React: type MyElem = ReturnType<React.FC<SomeProps>>
type ElemSet = MyElem | OtherElem | AnotherOne This quickly gets incomprehensible if |
I second this suggestion as well. If I create an alias, it's specifically to see the alias rather than seeing the true type which is often more complex. An option to resolve the alias on demand inside the tooltip would be nice but not necessary. |
Surely this would make a lot of intellisense computation less expensive
too, since it can terminate at the boundary of the type alias's name and
generic arguments
…On Mon, Jan 18, 2021 at 6:47 PM b6i6o6 ***@***.***> wrote:
I second this suggestion as well. If I create an alias, it's
*specifically* to see the alias rather than seeing the true type which is
often more complex. An option to resolve the alias on demand inside the
tooltip would be nice but not necessary.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#31940 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOXAMUWP3QA24EPYYFNP33S2RQ27ANCNFSM4HYYXEKQ>
.
|
I hugely appreciate this feature (or option). Showing internal structure instead of type alias name has never made any sense to me when I want to see the type of an identifier in a tooltip. This suggestion definitely helps the "Documentation as Code" idea. |
This issue is probably related to #202. Once we get true nominal typing in TS, then IntelliSense tooltips will be no longer allowed to replace such types entirely to their structures (though it may be good to show structures as annotation like the "Alternative" proposed in the original post). |
I honestly thought i had made a mistake when the alias type did not show up in intellisense. It really doesn't make sense to me when you set the alias explicitly like this. |
I just started using yup for input validation. An awesome aspect of it is that it produces the types out of the validation schema, so they're guaranteed to match. But Intellisense and error messages becomes completely useless when you get this: |
Like the above, I sometimes also like to see the type with aliases resolved. But not all the time. Perhaps it could be when you hold down a key before mousing over something, it resolves all the aliases, otherwise it keeps them. Like shift maybe. |
I found an ugly workaround by using Union Type. In this case, sadly, numerical type must be type casted to Using it for qualitative variable must be useful and less side effects. like type SomeId = number | Number |
@miyauchiakira A better workaround is branded types / nominal types. In this case you need to cast the original value (when you know it's of a certain type) but you can use a variable like the original type: type Degrees = number & { _brand: 'Degrees' };
type Radians = number & { _brand: 'Radians' };
const deg: Degrees = 90 as Degrees;
const rad: Radians = (deg / 180 * Math.PI) as Radians;
const bad: Radian = deg; // ERROR It's strange that some types are expanded, but for example My issue was that auto-generated types which can be very complex cause the error messages to become illegible, instead of displaying the (explicitly set) alias type. |
@plaa export declare type Product = yup.InferType<typeof productSchema> & { _brand: 'Product' }; |
@plaa @miyauchiakira By the way, strictly speaking, the proper term for that technique is "branded types" (or "type branding"). It is a workaround to mimic nominal typing in structural type system, but not "nominal types" itself. |
@miyauchiakira True, just adding |
This suggestion doesn't work with:
However, this works:
I have no idea why. |
+1 for this. Maybe this would work: by default, hovering over a type alias should simply show it's name, however while also holding CTRL key (or anything), it would expand the alias to what it actually is...? |
worked for me |
So issue is 4 years old, however still no solution from the TS team... Anyways, yet another TypeScript hack to have it working as expected. Since type HexColorCode = string & {} // Works fine
type UUID = `${string}-${string}-${string}-${string}` & {} // Will show `${string}-${string}-${string}-${string}` instead of UUID
type DateTime = Date & {} // Will show Date instead of DateTime , what I generally do is include some method from the original type in type HexColorCode = string & {}
type UUID = `${string}-${string}-${string}-${string}` & { toString: string['toString'] }
type DateTime = Date & { toString: Date['toString'] }; This fixes IntelliSense problem and doesn't clutter up the code with unnecessary stuff (like |
type alias<t> = t & { _?: never } // instead { _: never}
type my_type = alias<number | { "any": "complicate type" }> Worked for me If you don't see images click here | Visual explanation of how its work export type PairId = Readonly<`${AssetSymbol}_${AssetSymbol}`> type alias<t> = t & { _?: never }
export type PairId = alias<Readonly<`${AssetSymbol}_${AssetSymbol}`>> |
For those who want the opposite behavior (i.e., resolve the alias), use this: type Alias<T> = T extends T ? T : T;
type Resolve<T> = T & unknown;
type Degrees = Alias<number | undefined>; // this works
type Radians = Resolve<Alias<number | undefined>>; // this works
type ResolveDegrees = Resolve<Degrees>; // this doesn't work
const deg1: Degrees = 0;
const deg2: Degrees = undefined;
const deg3: Degrees = {}; // error
const rad1: Radians = 0;
const rad2: Radians = undefined;
const rad3: Radians = {}; // error |
Had similar issues with Zod and type Alias<T> = Pick<T, keyof T>; |
We have defined a bunch of "semantic sugar" type aliases like:
Status quo (bad): VS Code is resolving these along the alias chain in tooltips and IntelliSense suggestions (which kinda makes non-sense of the type alias in the first place)
(c.f. hovered tooltip over
this.url
at bottom)Better: Let VS Code show
UrlString
as type here instead ofstring
to aid developers with semantic sugar as of what type of string to expect.Alternative: Show both, i.e.
BufferingWebSocket.url: UrlString (= string)
.The text was updated successfully, but these errors were encountered: