Skip to content

Type parameter can leak out of a function instead of being bound to specific typeΒ #43961

Closed
@jsnajdr

Description

@jsnajdr

Bug Report

πŸ”Ž Search Terms

type parameter leaks out

πŸ•— Version & Regression Information

In the TS playground, the first version that shows the bug is 3.5.1. Version 3.3.3 also behaves incorrectly, but in a different way.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

function withP1<P>(p: P) {
  const m = <I>(from: I) => ({ ...from, ...p });
  return m;
}

const addP1 = withP1({ foo: 1 });
const added1 = addP1({ bar: 2 });

console.log(added1.foo, added1.bar);

const createTransform = <I, O>(tr: (from: I) => O) => tr;

function withP2<P>(p: P) {
  const m = <I>(from: I) => ({ ...from, ...p });
  return createTransform(m);
}

const addP2 = withP2({ foo: 1 });
const added2 = addP2({ bar: 2 });

console.log(added2.foo, added2.bar);

πŸ™ Actual behavior

The added2.foo expression reports a type error:

Property 'foo' does not exist on type '{ bar: number; } & P'.

The index.d.ts generated from this source has a declaration for addP2 that contains an undefined identifier P:

declare const addP2: <I>(from: I) => I & P;

On the other hand, the addP1 version works well:

declare const addP1: <I>(from: I) => I & { foo: number };

The only difference is that withP2 calls an additional createTransformer function which is an identity.

πŸ™‚ Expected behavior

Both P1 and P2 versions behave the same way and infer the return type correctly, without leaking the P type parameter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions