-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Allow type variables to be constrained singleton, causing lookup into a non-generic mapped type to substitute #25879
Labels
Comments
This was referenced Jul 23, 2018
4 tasks
RyanCavanaugh
added
Suggestion
An idea for TypeScript
In Discussion
Not yet reached consensus
labels
Aug 7, 2018
mattmccutchen
changed the title
Allow a lookup into a non-generic mapped type to substitute
Allow type variables to be constrained singleton, causing lookup into a non-generic mapped type to substitute
Aug 23, 2018
Open
4 tasks
This was referenced Jun 3, 2019
5 tasks
Hey, I've been digging into related issues lately (#13995 , #46899 , #27808 , etc), and from what I can tell, @mattmccutchen 's original code example now works without error (after a couple small tweaks). I.e. this passes now in TS 5.4.5: enum Axis {
ROW = "row",
COL = "col",
}
const AXIS_BRAND = Symbol();
type SpanId<A extends Axis> = string & { [AXIS_BRAND]: A };
type Rectangle = { [A in Axis]: SpanId<A> };
function getRectangleSide<A extends Axis>(rect: Rectangle, a: A): SpanId<A> {
return rect[a];
}
declare const rect: Rectangle;
const rowSide = getRectangleSide(rect, Axis.ROW); // SpanId<Axis.ROW>
const colSide = getRectangleSide(rect, Axis.COL); // SpanId<Axis.COL> So it's possible/likely this issue was fixed either by #43183 (which fixed #13995) or a related PR. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I feel awkward submitting this suggestion since I don't know if it will get enough votes to go anywhere, but I guess someone has to be the initial submitter for each suggestion...
Search Terms
mapped type indexed access type lookup type substitute substitution generic
Suggestion
Currently, a lookup into a mapped type, for example
{ [P in K]: Box<T[P]> }[X]
, is simplified by substitution (in this example, to produceBox<T[X]>
) only if the constraint typeK
is generic; this is unsound but I guess it was useful in some cases. I'd like to be able to constrain a type parameterX
to be a singleton type, causing substitution to occur (which is sound) regardless of whetherK
is generic.Use Case
Suppose we have a codebase with an enum
E
and many functions that simulate dependent types by taking a type parameterA extends E
(whereA
is intended to be a singleton type) along with a value of typeA
. Given a generic typeT<A extends E>
, we may want an object that contains aT<A>
for eachA
inE
, i.e.,{[A in E]: T<A>}
. Then we'd like to pass this object to a function along with a particular choice ofA
and have it manipulate the corresponding property. We should get a type error if the function uses the wrong property. Currently, a lookup type expression like{[A in E]: T<A>}[A1]
does not substitute (because the constraint typeE
is not generic), so all reads and writes to the property are checked using the constraint of the lookup type, which is{[A in E]: T<A>}[E]
, and in effect we get no distinction among the properties of the object.Specifically, I'm writing a structured spreadsheet tool that manipulates row and column IDs. A rectangle ID is a pair of a row ID and a column ID. I wanted to brand the row and column IDs differently to ensure I don't mix them up. I have many functions that are parameterized over an axis: for example,
getRectParentOnAxis
takes a rectangle and can either find the rectangle that covers the same column and a larger row, or the same row and a larger column.One current approach, which I've taken and I call the "generic index" hack, is to add an artificial type variable to every relevant type and function so that I can ensure the constraint type of the mapped type is always generic and the mapped type will always substitute. (See "Workaround" below.) This is ugly, but I wanted the checking badly enough to do it.
Examples
Workaround
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: