Skip to content

Interface 'MyInterface<T>' incorrectly extends interface - for named tuple type that has '...rest' param #51751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
pmunin opened this issue Dec 5, 2022 · 4 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@pmunin
Copy link

pmunin commented Dec 5, 2022

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

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Dec 5, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 5, 2022
@RyanCavanaugh RyanCavanaugh added the Help Wanted You can do this label Dec 5, 2022
@RyanCavanaugh
Copy link
Member

This is probably going to be extremely difficult to fix (or possibly trivial?). Weird stuff.

@fatcerberus
Copy link

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
Copy link
Author

pmunin commented Dec 7, 2022

fwiw having an interface extend a tuple seems like an odd thing to do

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
Copy link
Contributor

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 the propertiesRelatedTo determines that this source is not assignable to this target.

The case with MyInterface works OK because this type manages to get normalized during prior stages and it becomes equivalent to its base. Note that adding any properties to MyInterface prevents 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~.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

4 participants