Skip to content

Generic Constraints working incorrectly #29000

Closed

Description

@hronro

TypeScript Version: 3.2.2

Code

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

interface IName {
  name: string;
}

const callWithName =
  <T extends IName, R>(fn: (origianlArgs: T) => R, name: string) =>
    (arg: Omit<T, 'name'>) =>
      fn({
        ...arg,
        name,
      });

const greeting = (arg: { name: string }) => {
  console.log(`Hello ${arg.name}`);
}

const greetingToTom = callWithName(greeting, 'Tom');

greetingToTom({});

Expected behavior:
shouldn't have any type error

Actual behavior:
has a error:

Argument of type '{ name: string; }' is not assignable to parameter of type 'T'.

Playground Link:

https://www.typescriptlang.org/play/index.html#src=type%20Omit%3CT%2C%20K%20extends%20keyof%20T%3E%20%3D%20Pick%3CT%2C%20Exclude%3Ckeyof%20T%2C%20K%3E%3E%3B%0A%0Ainterface%20IName%20%7B%0A%20%20name%3A%20string%3B%0A%7D%0A%0Aconst%20callWithName%20%3D%0A%20%20%3CT%20extends%20IName%2C%20R%3E(fn%3A%20(origianlArgs%3A%20T)%20%3D%3E%20R%2C%20name%3A%20string)%20%3D%3E%0A%20%20%20%20(arg%3A%20Omit%3CT%2C%20'name'%3E)%20%3D%3E%0A%20%20%20%20%20%20fn(%7B%0A%20%20%20%20%20%20%20%20...arg%2C%0A%20%20%20%20%20%20%20%20name%2C%0A%20%20%20%20%20%20%7D)%3B%0A%0Aconst%20greeting%20%3D%20(arg%3A%20%7B%20name%3A%20string%20%7D)%20%3D%3E%20%7B%0A%20%20console.log(%60Hello%20%24%7Barg.name%7D%60)%3B%0A%7D%0A%0Aconst%20greetingToTom%20%3D%20callWithName(greeting%2C%20'Tom')%3B%0A%0AgreetingToTom(%7B%7D)%3B

Related Issues:

Activity

  1. jack-williams commented on Dec 13, 2018

    @jack-williams
    Collaborator

    EDIT: Outdated comment. I wont delete the comment so you can read the history if you want.

  2. jack-williams commented on Dec 13, 2018

    @jack-williams
    Collaborator

    No problem. If I were you I would edit your initial post with the new example (and I'll probably remove / edit my comment too).

    This looks familiar to other posts I've seen but I can't say if this is a duplicate. Your name parameter should be something like T["name"] though, as it might be the case that T is instantiated with something more precise than string, like "foobar".

    This seems to boil down to whether { name: T["name"]; } & Pick<T, Exclude<keyof T, "name">> should be assignable to T.

    Sorry I can't be more help!

  3. hronro commented on Dec 13, 2018

    @hronro
    Author

    Jack Williams (@jack-williams) Thanks. And I found a issue here which is similar: #28748

    So maybe my issue is duplicated?

  4. jack-williams commented on Dec 13, 2018

    @jack-williams
    Collaborator

    Possibly; this issue also looks similar #28821. I don't know enough to say if this is a duplicate so I would wait for someone more knowledgeable to drop by.

  5. DanielRosenwasser commented on Dec 13, 2018

    @DanielRosenwasser
    Member

    Potentially a dupe; I'll let Anders Hejlsberg (@ahejlsberg) decide.

  6. sveyret commented on Dec 15, 2018

    @sveyret

    Also similar to #28884.

  7. ahejlsberg commented on Dec 17, 2018

    @ahejlsberg
    Member

    Duplicate of #28884.

  8. added
    DuplicateAn existing issue was already created
    and removed
    BugA bug in TypeScript
    on Dec 17, 2018
  9. typescript-bot commented on Dec 20, 2018

    @typescript-bot
    Contributor

    This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  10. 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

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions