question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

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

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:17 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
weswighamcommented, Aug 5, 2019

I would, too, but as it turns out a Readonly<any> isn’t structurally compatible with a Readonly<{x: number}> because of how any feeds into mapped types…

1reaction
weswighamcommented, Aug 5, 2019

Unreliable is supposed to be “fallback to structural if varianced-based check fails” while Unmeasurable is “don’t use the variance result at all”. It was a bit of a compromise to continue to allow some things that checked with variance but not by structure, so the change would break less, iirc. In theory the only thing that would change by converting all Unreliable into Unmeasurable is performance, in practice I’m not sure that’s the case.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript arrow functions vs normal functions in interfaces ...
P.S. I browsed through a few SO questions, including this one about arrow function vs. normal function inside interface but none of them...
Read more >
7 The essentials of TypeScript - Exploring JS
Type inference is not guesswork: It follows clear rules (similar to arithmetic) for deriving types where they haven't been specified explicitly. In this...
Read more >
TSConfig Reference - Docs on every TSConfig option
A TSConfig file in a directory indicates that the directory is the root of a ... strictNullChecks ": false ... Strict Function Types...
Read more >
Grumbling on TypeScript - stafford williams
Grumbling on TypeScript · Missing Type Definitions won't slow me down# · TSX breaks Generic Arrow functions# · Whacky type inference on Generics...
Read more >
Overview - TypeScript
During type argument inference in TypeScript 3.4, for a call to a generic function that returns a function type, TypeScript will, as appropriate, ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found