Skip to content

Add a strict flag forbidding impossible generic declarations #26129

Description

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)

Activity

  1. ajafff commented on Aug 1, 2018

    @ajafff
    Contributor

    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

  2. ajafff commented on Aug 2, 2018

    @ajafff
    Contributor

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

    Andy (Andrewkraft) (@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.

  3. added
    DeclinedThe issue was declined as something which matches the TypeScript vision
    and removed on Oct 9, 2018
  4. RyanCavanaugh commented on Oct 9, 2018

    @RyanCavanaugh
    MemberAuthor

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions