Repository: TypeScript
Issue: Inconsistent behavior of rest tuple with optional elements followed by non-optional elements
Labels: Suggestion,Awaiting More Feedback

# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 🔎 Search Terms

<!--
  What search terms did you use when trying to find an existing bug report?
  List them here so people in the future can find this one more easily.
-->
variadic tuple optional element rest spread inference

### 🕗 Version & Regression Information

<!-- When did you start seeing this bug occur?

"Bugs" that have existed in TS for a long time are very likely to be FAQs; refer to
  https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs

If possible, please try testing the nightly version of TS to see if it's already been fixed.
For npm: `typescript@next`
This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly

Note: The TypeScript Playground can be used to try older versions of TypeScript.

Please keep and fill in the line that best applies:
-->
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about spreading tuples with optional elements

### ⏯ Playground Link

<!--
  A link to a TypeScript Playground "Share" link which shows this behavior

  The TypeScript Workbench can be used for more complex setups, try
  https://www.typescriptlang.org/dev/bug-workbench/

  As a last resort, you can link to a repo, but these will be slower for us to investigate.
-->
[Playground link with relevant code](https://www.typescriptlang.org/play?ts=4.8.4#code/C4TwDgpgBAKgjFAvFA2gOwK4FsBGEBOA-ALoDcAUKJLAExKoB0T8ANFAM7D4CWaA5mSgB6Iaky4CUAD5QMaACYQAZrwjy2nHv2JscGYBwAWAewwAbeVDxjsefNNkLlq9Ry68BDlJo-FyAY2M0TihgOAAuWARkFDIAoJDgGkiYOhimBjC2ACJDCDMzY2zBEVRc-MLi8nJFfzMAQ3xoJTl-YG4gqD4IYABVdgIACm55SJ9+NmMwdoTCSIBvKAAPObctPigAXwBKMfd+ChqIOsbm1pm0Lp6AeXw+fqGRvfXJu4BJeVXxO0npjuDVosVs8PFtdlAAG7GEaHFpoNr-KD+eoFACCYG4AB4YFAIEtgBAFOxHABrNDGADuaFi9FibF69ChIwAfIMsD0TKMoIMMo0+OxIigMjA2EDVuMNptiNskMyoL0ZfNyFAVVAmsAMPhLjymHyBYxmNLZVB2cBOTqGHrRTsKJtqsi0RjBt0+gN8NtSCrSsMuRKZYg5RKAiizOjuM6bncHu7PcJRD6QRMoMZ3p9ExsZHJFCo0Gp-XKma49AZ2CZzJZrAm1h5XnwPumHFnnLn5PnIdD5OQgA)

### 💻 Code

<!-- Please post the relevant code sample here as well-->
```ts
type T1 = [number?];
type T2 = [...T1, string]; // [number | undefined, string], but should be [number | undefined, string] | [string]
const t1: T1 = [];
const t2: T2 = [...t1, "hello"]; // ["hello"]

declare function getUser(id: string, options?: { x?: string }): string;

declare function getOrgUser(id: string, orgId?: number, options?: { x?: string }): void;

function callApi<T extends unknown[] = [], U = void>(method: (...args: [...T, { x?: string }]) => U) {
    return (...args: [...T]) => method(...args, {});
}

callApi(getUser);  // (id: string) => string
callApi(getOrgUser);  // (id: string, orgId?: string | undefined) => void, but should be (id: string, orgId: string | undefined) => void
```

### 🙁 Actual behavior

<!-- What happened, and why it was wrong -->

As pointed out when middle and leading rest elements in tuple types were introduced, optional elements are spread as if the element are non-optional but possibly undefined [(1)](https://github.com/microsoft/TypeScript/pull/41544/files#r537740178) [(2)](https://github.com/microsoft/TypeScript/pull/41544/files#r537750806). When a tuple with omitted optional values is spread as a non-trailing rest into a tuple, the values are shifted and don't match the tuple's type.

Related inference behavior was addressed in #39607, but currently a variadic rest tuple with optional elements can be inferred when the rest tuple is followed by non-optional elements. This is incorrect, because the inferred type permits omitted values, resulting in invalid spreads where elements are shifted around.

### 🙂 Expected behavior

<!-- What you expected to happen instead, and why -->

Spreading a tuple with optional elements should result in a type that accounts for potentially omitted optional elements.

Similarly, inferred variadic rest tuples should be restricted to only non-optional elements when followed by non-optional elements, because permitting omitted values results in invalid spreads where elements are shifted around.