Open beanbean97 opened 2 years ago
Duplicate of #45972. Used search terms: `source has but target allows only"
I'm... not sure this is a duplicate of that, since there are no leading rest elements here to make the analysis weirder. Maybe the same underlying issue is happening in both places?
Anyway this one feels more like a bug to me, since the following is fine:
const f1: (x: string | number) => void = x => { };
const f2: (x: string | number, y: string | number) => void = f1; // okay
const f3: (...args: [number, string] | [string, number]) => void = f2; // okay
And while transitivity of assignability isn't the be-all and end-all for TypeScript, it's nice to be able to reason about things this way when possible.
Sorry to copy my https://github.com/microsoft/TypeScript/pull/49218#issuecomment-1140416519 here:
I think the easiest way to solve all the related issues is to wrap all the arguments into a tuple with rest syntax, i.e.
item => {}
should become(...[item]) => {}
and([first, ...rest], foo, ...args) => {}
should work just like(...[[first, ...rest], foo, ...args]) => {}
.
Not exactly the same issue, but probably the same root cause:
const func: (arg1: string, arg2?: string) => void = (...args: [string] | [string, string]) => undefined; // Error
Also:
type Func = (...args: [string] | [string, string]) => void;
type Test = Func extends (arg1: string, ...args: any[]) => any ? true : false; // false
// Workaround:
type Test = Func extends (...args: infer Args) => any ? (Args extends [string, ...any[]] ? true : false) : false; // true
Bug Report
🔎 Search Terms
source has but target allows only
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
throw error
🙂 Expected behavior
no error