Skip to content

Destructuring with rename incorrectly inferred as any #38969

Closed
@remcohaszing

Description

@remcohaszing

TypeScript Version: Nightly or 3.9.x

Search Terms: never destructure

Expected behavior: The type of shouldBeNever is never.

Actual behavior: The type of shouldBeNever is any.

The issue also exists for synchronous functions, but the asynchronous example shows that everything works as expected when using Promise.then().

The same issue exists for unknown as well.

Code

interface AxiosResponse<T = never> { 
    data: T;
}

declare function get<T = never, R = AxiosResponse<T>>(): Promise<R>;

async function main() {
    // These work examples as expected
    get().then((response) => { 
        // body is never
        const body = response.data;
    })
    get().then(({ data }) => { 
        // data is never
    })
    const response = await get()
    // body is never
    const body = response.data;
    // data is never
    const { data } = await get<never>();

    // The following does not work as expected.
    // shouldBeNever should be never, but is any
    const { data: shouldBeNever } = await get();
}
Output
"use strict";
async function main() {
    // These work examples as expected
    get().then((response) => {
        // body is never
        const body = response.data;
    });
    get().then(({ data }) => {
        // data is never
    });
    const response = await get();
    // body is never
    const body = response.data;
    // data is never
    const { data } = await get();
    // The following does not work as expected.
    // shouldBeNever should be never, but is any
    const { data: shouldBeNever } = await get();
}
Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

Playground Link: Provided

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions