Skip to content

Allow users to customize the variance of built-in Array #52621

New issue

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

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

Already on GitHub? # to your account

Open
devanshj opened this issue Feb 5, 2023 · 4 comments
Open

Allow users to customize the variance of built-in Array #52621

devanshj opened this issue Feb 5, 2023 · 4 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@devanshj
Copy link

devanshj commented Feb 5, 2023

Bug Report

πŸ”Ž Search Terms

Array covariance hardcoded?, Array invariance, --noLib

πŸ•— Version & Regression Information

Tested with 4.9.5

⏯ Playground Link

https://tsplay.dev/WPzdYN

πŸ’» Code

// @noLib: true

interface Array<T>
  { [i: number]: T | undefined
  , push: (t: T) => number
  }

interface _Array<T>
  { [i: number]: T | undefined
  , push: (t: T) => number
  }

declare let as: Array<"a">
declare let abs: Array<"a" | "b">
abs = as

declare let _as: _Array<"a">
declare let _abs: _Array<"a" | "b">
_abs = _as

πŸ™ Actual behavior

The assignment abs = as compiles.

πŸ™‚ Expected behavior

The assignment abs = as should not compile, just like the assignment _abs = _as does not compile.

@devanshj devanshj changed the title Invariant Array with --noLib is not invariant Invariant Array with --noLib does not have invariant subtyping Feb 5, 2023
@RyanCavanaugh RyanCavanaugh added the Not a Defect This behavior is one of several equally-correct options label Feb 13, 2023
@RyanCavanaugh
Copy link
Member

This behavior is not userland-configurable. You can remove the check in getVariances if you want to try this out in your own fork to see how it would go, though

@devanshj
Copy link
Author

This behavior is not userland-configurable.

I don't think it's unreasonable to want to use a sound (or sounder) version of TypeScript by rewritings the types.

If not a bug then consider this a feature request.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature and removed Not a Defect This behavior is one of several equally-correct options labels Feb 13, 2023
@RyanCavanaugh RyanCavanaugh changed the title Invariant Array with --noLib does not have invariant subtyping Allow users to customize the variance of built-in Array Feb 13, 2023
@rotu
Copy link

rotu commented Jan 10, 2024

Strangely (or maybe not so strangely), this does work as you expect when using type aliases instead of interfaces playground:

type Array<T> = 
  { [i: number]: T | undefined
  , push: (t: T) => number
  }

Even if you explicitly use a variance annotation on the interface (interface Array<in out T>), it gets silently ignored, which is strange.

@rotu
Copy link

rotu commented Jan 10, 2024

I also notice that when defining Array as a generic type alias, the compiler's tooltips get mucked up:
image

And defining Array in terms of [] syntax causes a hard compiler crash #57009.

So maybe this isn't a good workaround for now.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants