Skip to content

Emtpy interface reduced to never in nested generic function  #49536

Closed
@panmenghan

Description

@panmenghan

Bug Report

I can't find the docs about this behavior or google. I am not sure this is a bug.

My intention was define the IEmpty interface and augment it later, but the compiler reduce the IEmpty interface to never, my current workaround that have to define two dummy properties or not use nested function(or closure).

Is there a right way to force the compiler to keep the IEmpty in nested generic function?

🔎 Search Terms

closure, nested, generic, emtpy interface, never, narrow

🕗 Version & Regression Information

  • This is the behavior from v4.2.3 to v4.7.3

⏯ Playground Link

Playground link with relevant code

💻 Code

// empty interface
interface IEmpty {}

export function func<T extends keyof IEmpty>() {}

export function makeFunc() {
  function nestedFunc<T extends keyof IEmpty>() {}
  return nestedFunc
}


// interface with one property
interface IOneProperty {
  a: string
}

export function funcOneProperty<T extends keyof IOneProperty>() {}

export function makeFuncOneProperty() {
  function nestedFunc<T extends keyof IOneProperty>() {}
  return nestedFunc
}


// interface with two properties
interface ITwoProperty {
  a: string
  b: string
}

export function funcTwoProperty<T extends keyof ITwoProperty>() {}

export function makeFuncTwoProperty() {
  function nestedFunc<T extends keyof ITwoProperty>() {}
  return nestedFunc
}

🙁 Actual behavior

.D.TS output:

interface IEmpty {
}
export declare function func<T extends keyof IEmpty>(): void;
export declare function makeFunc(): <T extends never>() => void;  // <-- unexpected: `keyof IEmpty` replaced by `never`
interface IOneProperty {
    a: string;
}
export declare function funcOneProperty<T extends keyof IOneProperty>(): void;
export declare function makeFuncOneProperty(): <T extends "a">() => void; // <-- same here
interface ITwoProperty {
    a: string;
    b: string;
}
export declare function funcTwoProperty<T extends keyof ITwoProperty>(): void;
export declare function makeFuncTwoProperty(): <T extends keyof ITwoProperty>() => void;
export {};

🙂 Expected behavior

.D.TS output:

interface IEmpty {
}
export declare function func<T extends keyof IEmpty>(): void;
export declare function makeFunc(): <T extends IEmpty>() => void;
interface IOneProperty {
    a: string;
}
export declare function funcOneProperty<T extends keyof IOneProperty>(): void;
export declare function makeFuncOneProperty(): <T extends IOneProperty>() => void;
interface ITwoProperty {
    a: string;
    b: string;
}
export declare function funcTwoProperty<T extends keyof ITwoProperty>(): void;
export declare function makeFuncTwoProperty(): <T extends keyof ITwoProperty>() => void;
export {};

Metadata

Metadata

Assignees

Labels

Needs InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions