镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

literal function with structure spread can't be rightly inferred in function's generic type slot #28816

Description

@zheeeng

TypeScript Version: 3.2.1

Search Terms:

strucutre spread + generic

Code

function id<T>(input: T): T { return input }

function getFoo ({ foo = 42 }) {
  return foo
}

const newGetFoo = id(getFoo)
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
  return foo
})

Expected behavior:

newGetFoo and newGetFoo2 should have the same signature

Actual behavior:

newGetFoo is:

({ foo }: {
    foo?: number | undefined;
}) => number

but newGetFoo2 is

 ({ foo }: any) => number

Playground Link:
http://www.typescriptlang.org/play/index.html#src=function%20id%3CT%3E(input%3A%20T)%3A%20T%20%7B%20return%20input%20%7D%0A%0Afunction%20getFoo%20(%7B%20foo%20%3D%2042%20%7D)%20%7B%0A%20%20return%20foo%0A%7D%0A%0Aconst%20newGetFoo%20%3D%20id(getFoo)%0Aconst%20newGetFoo2%20%3D%20id(function%20getFoo%20(%7B%20foo%20%3D%2042%20%7D)%20%7B%0A%20%20return%20foo%0A%7D)%0A

Related Issues:

Activity

  1. ahejlsberg commented on Jan 25, 2019

    @ahejlsberg
    Member

    Our intended design is to determine the type of a parameter from one of the following, in order of preference:

    1. Explicit type annotation
    2. Contextual parameter type
    3. Initializer type
    4. Type implied by binding pattern

    See original discussion and rationale here.

    For the getFoo function we end up using the type implied by the binding pattern (i.e. ({ foo }: { foo?: number }) => number) because there is no type annotation, contextual type, or initializer type. This is working as intended.

    However, for the function expression passed as an argument to id we do have a contextual type, namely T. Since T has no constraint we should end up inferring an implicit any type for the parameter, but this isn't quite working correctly.

    So, the bug here is that newGetFoo2 should have type ({ foo }: any) => any and in -noImplicitAny mode we should report an implicit any error on foo.

    EDIT: In retrospect, I now agree newGetFoo2 should have the same type as getFoo and newGetFoo. #36476 has the fix.

  2. ahejlsberg commented on Jan 28, 2020

    @ahejlsberg
    Member

    Fix in #36476 now produces the result expected in the original post.

  3. added
    Fix AvailableA PR has been opened for this issue
    and removed
    FixedA PR has been merged for this issue
    on Jan 28, 2020
  4. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions