Interface 'MyInterface<T>' incorrectly extends interface - for named tuple type that has '...rest' param #51751
Copy link
Copy link
Open
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: Something ElseFallback label when we just can't figure anything else outFallback label when we just can't figure anything else outHelp WantedYou can do thisYou can do this
Milestone
Description
Bug Report
Error happens only when:
- MyInterface extends type alias which represents named array tuple
- MyInterface is generic
- MyType is NAMED tuple
- MyType has
...rest
🔎 Search Terms
type alias, named tuple, interface
🕗 Version & Regression Information
Typescript v4.9.3
⏯ Playground Link
Playground link with relevant code
💻 Code
The following code throws that error:
type MyType = [
name1:string,
name2: number,
...rest:any[]
]
interface MyInterface<T> extends MyType {
}
// "Interface 'MyInterface<T>' incorrectly extends interface '[name1: string, name2: number, ...rest: any[]]'.All of the following below works fine:
type MyType = [
name1:string,
name2: number,
...rest:any[]
]
interface MyInterface extends MyType { //MyInterface is not generic => works
}
// ----------- OR -------------
type MyType = [ // MyType does not have ...rest => works fine
name1:string,
name2: number
]
interface MyInterface<T> extends MyType {
}
// ------------ OR ------------
type MyType = [ // MyType typle elements are not named => works fine
string,
number,
...any[]
]
interface MyInterface<T> extends MyType {
}🙁 Actual behavior
TSC throws error:
Interface 'MyInterface<T>' incorrectly extends interface '[name1: string, name2: number, ...rest: any[]]'.
🙂 Expected behavior
Successfull compilation
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: Something ElseFallback label when we just can't figure anything else outFallback label when we just can't figure anything else outHelp WantedYou can do thisYou can do this
Activity
RyanCavanaugh commentedon Dec 5, 2022
This is probably going to be extremely difficult to fix (or possibly trivial?). Weird stuff.
fatcerberus commentedon Dec 6, 2022
fwiw having an interface extend a tuple seems like an odd thing to do in the first place. If the interface has any properties or methods then I don’t think you can even construct a legal value (without type assertions, anyway).
pmunin commentedon Dec 7, 2022
The main (maybe only?) reason to use interface vs type alias is ability to merge declarations. That constraint of type alias was an odd design decision, also even having types+interfaces vs just one of those that combines everything is weird and confusing
Andarist commentedon Mar 24, 2023
It probably wouldn't be that hard to fix but it would increase the complexity of the code a little bit.
It doesn't work because the interface checks if it's extending the base type correctly. To do that it checks if that resulting interface it's assignable to all of its bases. So it's checking if
MyInterface<T>to[string, number, ...any[]]. The target is a tuple type but the source is not an array and it's not a tuple and since the target tuple is variable thepropertiesRelatedTodetermines that this source is not assignable to this target.The case with
MyInterfaceworks OK because this type manages to get normalized during prior stages and it becomes equivalent to its base. Note that adding any properties toMyInterfaceprevents that and it also errors.Cases without a variable element on that tuple likely work because the compiler is able to get past that "is tuple variable" check and actually gets to comparing object properties~.