Skip to content
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

Add a strict flag forbidding impossible generic declarations #26129

Closed
3 of 4 tasks
RyanCavanaugh opened this issue Aug 1, 2018 · 4 comments
Closed
3 of 4 tasks

Add a strict flag forbidding impossible generic declarations #26129

RyanCavanaugh opened this issue Aug 1, 2018 · 4 comments
Labels
Add a Flag Any problem can be solved by flags, except for the problem of having too many flags Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@RyanCavanaugh
Copy link
Member

Search Terms

generic declaration return type parameter

Suggestion

Today you can write declarations like this:

function getThing<T>(): T {
  return null as any as T; // ¯\_(ツ)_/¯
}
const x = getThing<"cool">(); // Type safety!

This isn't particularly meaningful - getThing has no plausible correct implementation that doesn't rely on the caller asking for the correct type by coincidence.

We then also started allowing this to enable some other scenarios (#16072):

// This will return a number because I wished for it
const p: number = getThing();

See also #5256 (comment)

The rule should be: All type parameters must appear in an input position; this would need to be under some flag like --strictTypeParameterDeclarations (please bikeshed).

Users should return any or unknown instead in these cases.

A lint rule approximating this can be done syntactically so we should scan DefinitelyTyped to see what the breakage would look like.

Use Cases

Mostly to allow us to clean up DefinitelyTyped.

Examples

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)
@ajafff
Copy link
Contributor

ajafff commented Aug 1, 2018

Re: lint rule
I have implemented such a rule a while ago: https://github.com/fimbullinter/wotan/blob/master/packages/mimir/docs/no-misused-generics.md
As you can see in the docs it does a bit more than what you are looking for in this proposal.
Here's the test baseline for this rule: https://github.com/fimbullinter/wotan/blob/master/baselines/packages/mimir/test/no-misused-generics/default/test.ts.lint

@ghost
Copy link

ghost commented Aug 2, 2018

There should be an exception for functions like function createArray<T>(): T[]. But not for function createWrapper<T>(): { wrapped: T }. Or, we could allow people to ignore the error when they need to (#19139). But this is starting to seem like a lint rule.
dtslint's no-unnecessary-generics does a similar thing.

@ajafff
Copy link
Contributor

ajafff commented Aug 2, 2018

dtslint's no-unnecessary-generics does a similar thing.

@andy-ms last time I looked at the source code of that rule it had false negatives with other Identifiers:

declare function test<T>(param: {T: any}): any;

I'll open a separate issue in dtslint's repo.

@RyanCavanaugh RyanCavanaugh added the Add a Flag Any problem can be solved by flags, except for the problem of having too many flags label Aug 22, 2018
@RyanCavanaugh RyanCavanaugh added Declined The issue was declined as something which matches the TypeScript vision and removed In Discussion Not yet reached consensus labels Oct 9, 2018
@RyanCavanaugh
Copy link
Member Author

Too many people on DT [ab]use this; "errors" of this sort can be syntactically detected anyway by a lint rule

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Add a Flag Any problem can be solved by flags, except for the problem of having too many flags Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants