microsoft / microsoft/TypeScript

Incorrect inference of arrow function with intersected mapped type argument under strictFunctionTypes

Open
#32,664 17 comments 0 reactions 1 assignee View on GitHub

@weswigham is already working on this.

Since Aug 1, 2019.

Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

TypeScript Version: 3.6.0-dev.20190801

Search Terms: inference intersection type strictFunctionTypes

Code

type MappedIntersection<T extends {}> = { [P in keyof T]: string } & {};
type MappedRaw<T extends {}> = { [P in keyof T]: string };

// Case 1: Intersection + no arrow = succeed
type ToInferNoArrowIntersection<T extends {}> = {
    fn(params: MappedIntersection<T>): void;
};

type NoArrowIntersection<T extends ToInferNoArrowIntersection<any>> = void;
declare const case1: NoArrowIntersection<{
    fn: (params: MappedIntersection<{a: 1}>) => string,
}>;


// Case 2: No intersection + arrow = succeed
type ToInferArrowNoIntersection<T extends {}> = {
    fn: (params: MappedRaw<T>) => void;
};

type ArrowNoIntersection<T extends ToInferArrowNoIntersection<any>> = void;
declare const case2: ArrowNoIntersection<{
    fn: (params: MappedRaw<{a: 1}>) => void,
}>;


// Case 3: Intersection + arrow = fail
type ToInferArrowIntersection<T extends {}> = {
    fn: (params: MappedIntersection<T>) => void;
};

type ArrowIntersection<T extends ToInferArrowIntersection<any>> = void;
declare const case3: ArrowIntersection<{ // Fails here
    fn: (params: MappedIntersection<{a: 1}>) => void,
}>;

Expected behavior:
Expected case 3 to succeed.

Actual behavior:
Case 3 produces:

 Type '{ fn: (params: { a: string; }) => void; }' does not satisfy the constraint 'ToInferArrowIntersection<any>'.
  Types of property 'fn' are incompatible.
    Type '(params: { a: string; }) => void' is not assignable to type '(params: { [x: string]: string; }) => void'.
      Types of parameters 'params' and 'params' are incompatible.
        Property 'a' is missing in type '{ [x: string]: string; }' but required in type '{ a: string; }'.

Seems relevant that compilation succeeds without strictFunctionTypes

Playground Link: Playground

Related Issues:
https://github.com/microsoft/TypeScript/issues/29123#issuecomment-453884098
https://github.com/microsoft/TypeScript/issues/31081

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.