Skip to content

Provide a way to omit first generic parameter when it can be inferredΒ #59629

@fwolff

Description

@fwolff

πŸ” Search Terms

generic parameters, type inference

βœ… Viability Checklist

⭐ Suggestion

When a type is created with two or more generic parameters (eg. type Context<T, P = any>), the first parameter can be inferred only if the second one isn't provided explicitly (see example).

πŸ“ƒ Motivating Example

In this example, Test3 doesn't compile, the first parameter cannot be inferred and must be duplicated if the second one is provided:

type Context<T, P = any> = {
    value: T
    parent: P
}

type DecoratorProps<T, P = any> = {
    callback: (context: Context<T, P>) => void
}

function decor<T>(callback: (context: Context<T>) => void) {
    return function _(_: any, context: ClassFieldDecoratorContext<unknown, T>) {
        const metadata = context.metadata! as Record<PropertyKey, DecoratorProps<T>>
        metadata[context.name] = { callback }
    }
}

class Test {
    @decor((context) => {}) // (parameter) context: Context<string | null, any>. T is correctly inferred
    name: string | null = null
}

class Test2 {
    @decor((context: Context<string | null, Test>) => {}) // (parameter) context: Context<string | null, Test>, T signature must be duplicated
    name: string | null = null
}

class Test3 {
    @decor((context: Context<, Test>) => {}) // Doesn't compile: Type expected. 
    name: string | null = null
}

See playground here.

πŸ’» Use Cases

  1. What do you want to use this for? avoid duplicating types that could be inferred
  2. What shortcomings exist with current approaches? the syntax Context<, Test> is only a possible option, another way to express this type omission would be fine.
  3. What workarounds are you using in the meantime? provide the first parameter like in Test2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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