Skip to content

Enforcing types to be narrowed from generic types #26332

Description

@LinusU

Search Terms

enforce narrowing, narrow types, narrow, force narrow type

Suggestion

First of all, sorry if there is already a way to do this, I've been reading thru the documentation, searched thru the issues, and crawled the web in order to find anything, but haven't so far.

I would like a way to force narrow types to be passed to my function, and specifically disallow the generic versions (e.g. string, number, boolean).

What I want is for my function to accept any subtype of e.g. string, but not string itself. So both 'a' | 'b', 'a', and 'hello' | 'world' | '!' would be accepted, but not string.

Use Cases

I think that this is one of the most illustrating use cases:

mafintosh/is-my-json-valid#165

Basically, I want to have a type that maps a JSON Schema into a TypeScript type. I then provide a function with a return value of input is TheGeneratedType.

Currently, the enum values need to be typed with 'test' as 'test' in order not to be generalized as just string:

// Current behavior:
function foobar<{ enum: [1, 2, 3] }>(input: any): input is number

// Wanted behavior:
function foobar<{ enum: [1, 2, 3] }>(input: any): input is 1 | 2 | 3

Examples

interface EnumSchema {
  enum: SubtypeOf<string>[] | SubtypeOf<number>[] | SubtypeOf<boolean>[]
}

function foobar(input: EnumSchema)

// Illigal
foobar({ enum: ['test' as string] })

// Allowed
foobar({ enum: ['test'] })

Related

#16896

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions