Skip to content

Generic parameters are sometimes not optional when their type resolves to void #43820

Closed
@bave8672

Description

@bave8672

Bug Report

🔎 Search Terms

Generic function method static constructor void optional required

🕗 Version & Regression Information

  • Tested up to 4.3.0-beta
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about generics and function signatures.

⏯ Playground Link

https://www.typescriptlang.org/play?ts=4.2.3#code/PQKhAIGUBcEMDsAmsBOjwDcD2BLdAjAUwAtYMcsVwRgAoAMwFd4BjaC+cegHgBUA+ABQAPAFyZciAJTgA3gF8Gg5okL0c8QtIDc4YMHAB5ANJKpu-UdO1QEAGqTwRUuSyMqAd2KFOjAM4aAObgAAaEwtA+iH4h4H4AnvBwwtR0TKzsWJyBfEJi4Lzg4ZFIfuAI8eAA-BJ44OLYeDIKtIHKSGoaWjKWJq2C5noGAKLCAA6EbFrgAIzlKIGMALY+0H4ANE6M0OCBWDsADAB0rdx+0ChBQoOWoxNT6HOoiytJG1s7e4cnOfDLRChrhYRuNJpFHvMXqt3vhtrt9uBjrQbGBwABhAA2sD8ZXCsCWYwxhHAAFpwPB9sToKQditqVhouUxhNUOBoFgnCQyMTsUVQQ9UrQWFiceAAIK5OS0cAy8AsLLnFCMNiUETiQrFKJlP5LAHVWroBqSZqKWVxODsFhcXJqgp8kqMnV6mqNQ0Gk3S2X0W0aiJa8n-QhUF2OI1NOSKRSaDzis4XK4DYHgYYoFCUcR3MHTJ4LZbQzawz4IpFio48RUJm4jVPp5P88GzSF5t4FuFfRG0aOxivwQJCFSdTTSMuJoZWWhAA

💻 Code

/** Standard void behavior */
function f<T>(x: void) {}
f(undefined); // OK
f(); // OK

/** Void behavior when using `extends` syntax */
function g<T>(x: T extends any ? void : void) {}
g(undefined) // OK
g(); // Expected 1 arguments, but got 0.
g<string>(); // Expected 1 arguments, but got 0.
g<number>(); // Expected 1 arguments, but got 0.

/** Class example - note that methods appear to behave as expected */
class A<T> {
    constructor(x: T extends number ? void : void) {}
    static f<T>(x: T extends number ? void : void) {}
    f(x: T extends number ? void : void) {}
}
new A<string>(); // Error: Expected 1 arguments, but got 0.
A.f<string>(); // Error: Expected 1 arguments, but got 0
new A<string>(undefined).f(); // OK

🙁 Actual behavior

For functions, static methods, constructors, that use the extends syntax, typescript treats void arguments as required.

🙂 Expected behavior

Arguments that are known to be void are always treated as optional.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions