-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Type assertion on unspecified generic return type changes the type #36062
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
Comments
There isn't a way to do this; the type of the expression really truly actually for real is Hopefully this has the end effect of dissuading people from writing functions like |
A real world example of this is (edit: older versions of lodash typings, that is) interface lodashGet<TObject, TResult> {
(object: TObject, path: string | string[], defaultValue?: TResult): TResult;
} const result = lodashGet(object, 'foo.bar') as number; |
Overrides are one way to work around that specific one: function lodashGet<TObject, TResult>(object: TObject, path: string | string[]): unknown;
function lodashGet<TObject, TResult>(object: TObject, path: string | string[], defaultValue: TResult): TResult;
function lodashGet<TObject, TResult>(object: TObject, path: string | string[], defaultValue?: TResult): TResult {
// pretend this works
} …but I'm wary of having to patch common libraries when they have generic return types that are optional like that |
I was trying to find that definition, but it looks like the types for lodash's |
Oh, nice find! I can upgrade my type declarations to mitigate that instance then 👍 Seems likely to come up in other contexts though? |
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow. |
TypeScript Version: nightly (on playground).
Search Terms:
generic, return, assertion, inference, checker api.
Code
Expected behavior:
In both cases, the return type of
genericGet(object, 'foo.bar')
reported by the type checker API (checker.getTypeAtLocation
) should beunknown
.Actual behavior:

In the first case, the return type of
genericGet(object, 'foo.bar')
reported by the type checker API isunknown
.In the second case, the return type is

number
.(best shown via ts-ast-viewer, link below).
Playground Link:
https://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=7&pc=56#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXwHMRUQYswBxEDAHgBUA1KCZEAPgAocAjAK3AwAueFFQBPADTwADlAwALYQGcMZVAQCUwxs1YAoPWDwr4PfpngBeeAG8kOHMLvdYwgIwAmAMzwAvn4BuQ2MMeDglZAgMNytCYlJyKgwuPgEpAHJEBwA6Fxh0jSCjVBNwyIwPWKISMkpqFPMMDKycXNgCkSV4VGQAW25SAKA
https://ts-ast-viewer.com/#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXwHMRUQYswBxEDAHgBUA1KCZEAPgAocAjAK3AwAueFFQBPADTwADlAwALYQGcMZVAQCUwxs1YAoPWDwr4PfpngBeeAG8kOHMLvdYwgIwAmAMzwAvn4BuQ2MMeDglZAgMNytCYlJyKgwuPgEpAHJEBwA6Fxh0jSCjVBNwyIwPWKISMkpqFPMMDKycXNgCkSV4VGQAW25SAKA
Related Issues:
#31435
Loosely related to: #35431
Related issue in typescript-eslint:
typescript-eslint/typescript-eslint#1410
Related rule logic:
https://github.com/typescript-eslint/typescript-eslint/blob/aee723813ec47ccac0a165cf1bc9674f6257b609/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts#L244-L292
I found #31435, which seems to suggest that this is entirely intentional.
However I would like to question this from the context of the type checker API.
This makes the type API pretty hard to use for certain use cases. Inspecting the type of the assertion expression (via
checker.getTypeAtLocation
) says it's of type number, and similarly inspecting the type of the call expression via the same API says it's of type number.Is there any way to get the type that hasn't been inferred from a return type assertion?
In the context of our
no-unnecessary-type-assertion
rule, the rule warns about assertions that don't do anything, so that there is less useless code in a codebase..(i.e.
genericGet(object, 'foo.bar') as number
is necessary, because it assertsunknown
tonumber
, butgenericGet<number>(object, 'foo.bar') as number
is unnecessary, because the return type is alreadynumber
).The text was updated successfully, but these errors were encountered: