Closed as not planned
Description
🔎 Search Terms
named tuples, equal, unequal
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ
This happens in typescript@next
, typescript@latest
, and all the way back to [email protected]
(the earliest version that has tuples in the playground).
⏯ Playground Link
💻 Code
// This equality check is commonly used in libraries. It's used because it's a stricter sense of equality than mutual assignability.
// I personally ran into it this in a repo using `vitest`.
type Equals<T, U> =
(<V>() => V extends T ? true : false) extends (<V>() => V extends U ? true : false)
? true
: false;
type TestUnnamedTuples = Equals<[string], [string]>;
// ^ true
// This is reliably true.
// This is likely because a tuple's name is an `Identifier` and a part of the cache key.
// Because these are unnamed they properly get thought of as identical. (Thanks Andarist for this find!)
type OptionalTuple = [param?: string];
type TestTypeAliasOptionalTuples = Equals<OptionalTuple, OptionalTuple>;
// ^ true
// This is reliably true; the type ids are always equal.
type TestTuples = Equals<[param: string], [param: string]>;
// ^ false
// Should be `true`.
type TestOptionalTuples = Equals<[param?: string], [param?: string]>;
// ^ false
// Should be `true`.
export {};
declare global {
interface Array<T> {
// The names do not matter.
// someMethod<O>(other: Extract<O, T>): [Extract<T, O>]; // Swapping out for this makes only optional tuples compare unequally.
someMethod<O>(other: O extends T ? O : any): [T extends O ? any : any]; // This makes both optional and non-optional tuples compare unequally.
}
}
🙁 Actual behavior
TestTuples
and TestOptionalTuples
are false
whereas TestTypeAliasOptionalTuples
and TestUnnamedTuples
are true.
🙂 Expected behavior
For all of these tests to return true.
Additional information about the issue
While this someMethod
merge is obviously contrived, I actually ran into this while typing a library that adds an Array.equals
and Array.partition
method.
After hunting it down I simplified the types to find this case.