Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typing on function behaves differently if as type, interface or on the function #43365

Closed
mmahalwy opened this issue Mar 25, 2021 · 7 comments
Closed
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@mmahalwy
Copy link

mmahalwy commented Mar 25, 2021

Bug Report

No error:

type CustomType = { name: string };
interface MyFunc {
  (arg: string): CustomType;
}

const myFunc: MyFunc = (arg) => {
  return { name: arg, extraKey: 1234 };
};

No error:

type CustomType = { name: string }
type MyFunc = (arg: string) => CustomType;

const myFunc: MyFunc = (arg) => {
  return { name: arg, extraKey: 1234 };
};

Errors:

type CustomType = { name: string }

const myFunc = (arg: string): CustomType => {
  return { name: arg, extraKey: 1234 };
};

// error: Type '{ name: string; extraKey: number; }' is not assignable to type 'CustomType'.
//  Object literal may only specify known properties, and 'extraKey' does not exist in type 'CustomType'.

🔎 Search Terms

Function types not erroring when using type or interface.

🕗 Version & Regression Information

Version 4.2.3

Tested from version 3.3.3 to 4.2.3

⏯ Playground Link

N/A

Playground link with relevant code

💻 Code

See above

🙁 Actual behavior

Only the last example fails.

🙂 Expected behavior

All examples above should error. The function returns an object with incorrect keys.

@MartinJohns
Copy link
Contributor

This is working as intended. In your no error versions you don't specify a return type for your functions, so the return type is inferred. Because the return type is inferree based on your returned value you don't get any excess properties. Then the compiler checks if your value (the function) is compatible with the annotated type of your variable (MyFunc).

@mmahalwy
Copy link
Author

I may have missed this @MartinJohns. For this example, why is the return type inferred? I thought I set it explicitly as CustomType. See:

type CustomType = { name: string }
type MyFunc = (arg: string) => CustomType;

const myFunc: MyFunc = (arg) => {
  return { name: arg, extraKey: 1234 };
};

@MartinJohns
Copy link
Contributor

Because your anonymous arrow function has no type annotation for the return type:

// No return type annotation
(arg) => { return { name: arg, extraKey: 1234 }; }

// With return type annotation
(arg): { name: string } => { return { name: arg, extraKey: 1234 }; }

Keep in mind that additional properties are legal in TypeScript. The excess property checks feature is often called "more of a linter feature" by the TypeScript team.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Mar 25, 2021
@mmahalwy
Copy link
Author

Right, I understand that example @MartinJohns but since I am setting the type on the function constant, I'd expect it to adhere to the return type annotation:

type MyFunc = (arg: string) => CustomType;
const myFunc: MyFunc;

@RyanCavanaugh
Copy link
Member

See also #40311 which attempts to change this

@mmahalwy
Copy link
Author

@RyanCavanaugh thanks for linking that. Would LOVE to see that PR merged 🙏

@typescript-bot
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants