microsoft / microsoft/TypeScript

Optional type as required if used in one branch of nested promises

Open
#42,293 2 comments 0 reactions 1 assignee View on GitHub

@rbuckton is already working on this.

Since Jan 12, 2021.

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

Description

Bug Report

The system falsely reports an optional property as required if one branch returns the one optional property, but a second branch skips it and returns another optional property.

🔎 Search Terms

promise, catch, optional property

🕗 Version & Regression Information
  • 3.1.4
  • nightly (4.2.0-dev.20210112)
⏯ Playground Link

This playground shows 3 examples of the code posted below, where I commented out specific parts of the code. If you remove the comments in a variant, it will show the error:

https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBDAnmYcAiBDGG4F44AKUEAtgJYDOwAPAN4BQcTcUwAjgK5msAmREKWIgBccAHYcSAI2BQA3I2YCYZCGIwAbfoKQBGAPyiJ02QuZxlq9VuI7EAJkPjJM+fQC+APjNx6AYzUKeAA3DCgyDCkNYFFMbDxCYnIqADpWCggNYOAACnsASnoUmAALYDEcnLBiACtgPxh8vE84BiYyADM4HIBCaog6hqa25lYYDigxVsVzVk5uYD5bWSRRAAYAGhmlMBU1TW0VxF1Re03t9x93OGANKmnzAHpHsYmp-mTgNOAMrNyAbQAuvlimUKjkmrgWiNZsBxpMHuZRuwuLxDkJ1lskTs9tZ0Uh7KJdOdsZdts93Pkrh5Cik-Fg-CVKpCWjkRpZ9jYBEcTnBiViWCiFktuRi4OdKVT6P5AiEwhEosBCegsDh8B9KF90plsnlaaVypV+oNGs1EZ1un1avVTTDBfCpnamHNUYt8SJxQKno8OXjlkJeWcvXAyUxrrd7nbXgiNaltX8ckCQQbwSzEbCHemkS7he7MdtzL6Dv6CUSSUjQ8xKdTKUV6TBGcyzWzFEWuXZefzFDm0SWPRL8lKZWIgnBQuFItEAMyxVUJWNan463IFIopo3WoZmkYW3rGm3DbbRx0FwXzXui1ae09t92B8thq43O6oKNwt6JUia76-XVJ0GGhC26nseWawuebp9vm2JMLefbKl2pI+GGUphjS9DPHSDJMkBULdAwzywbsVjFpexxllshFnq6Ip2PmFKDgow6-F8GgQAA5jk44KtEGxjvKk5Knx3GCVOhRAA

💻 Code
export type Data = Promise<{
    requiredProperty: number;
    optionalProperty1?: number;
    optionalProperty2?: number;
}>;
  
const variable: Data = Promise.resolve(2)
.then((project) => {
  if (!project) {
    return {
      requiredProperty: 0,
      optionalProperty1: 20,
    };
  } else {
    return Promise.resolve([]).then(() => {
      return {
        requiredProperty: 0,
        optionalProperty2: 10,
      };
    });
  }
})
.catch(() => ({
  optionalProperty1: 10,
  requiredProperty: 0,
}));
🙁 Actual behavior
⠏ (3/3) Building...
test.ts:7:7 - error TS2322: Type 'Promise<number | { optionalProperty1: number; requiredProperty: number; }>' is not assignable to type 'Data'.
  Type 'number | { optionalProperty1: number; requiredProperty: number; }' is not assignable to type '{ requiredProperty: number; optionalProperty1?: number | undefined; optionalProperty2?: number | undefined; }'.
    Type 'number' is not assignable to type '{ requiredProperty: number; optionalProperty1?: number | undefined; optionalProperty2?: number | undefined; }'.

7 const variable: Data = Promise.resolve(2)
        ~~~~~~~~


test.ts:8:7 - error TS2345: Argument of type '(project: number) => Promise<{ requiredProperty: number; optionalProperty2: number; }> | { requiredProperty: number; optionalProperty1: number; }' is not assignable to parameter of type '(value: number) => { requiredProperty: number; optionalProperty2: number; } | PromiseLike<{ requiredProperty: number; optionalProperty2: number; }>'.
  Type 'Promise<{ requiredProperty: number; optionalProperty2: number; }> | { requiredProperty: number; optionalProperty1: number; }' is not assignable to type '{ requiredProperty: number; optionalProperty2: number; } | PromiseLike<{ requiredProperty: number; optionalProperty2: number; }>'.
    Type '{ requiredProperty: number; optionalProperty1: number; }' is not assignable to type '{ requiredProperty: number; optionalProperty2: number; } | PromiseLike<{ requiredProperty: number; optionalProperty2: number; }>'.
      Property 'optionalProperty2' is missing in type '{ requiredProperty: number; optionalProperty1: number; }' but required in type '{ requiredProperty: number; optionalProperty2: number; }'.

8 .then((project) => {
        ~~~~~~~~~~~~~~

  test.ts:18:9
    18         optionalProperty2: 10,
               ~~~~~~~~~~~~~~~~~~~~~
    'optionalProperty2' is declared here.

ℹ (3/3) Building...found 2 errors
🙂 Expected behavior

Should work without reporting any errors.

Please explain if this was intended in any way.

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.