Skip to content
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

Indexing mapped type with keyof type param #16018

Closed
liam-goodacre-hpe opened this issue May 23, 2017 · 7 comments
Closed

Indexing mapped type with keyof type param #16018

liam-goodacre-hpe opened this issue May 23, 2017 · 7 comments
Labels
Duplicate An existing issue was already created

Comments

@liam-goodacre-hpe
Copy link

TypeScript Version: 2.2.2

Code

On playground

type Eg = { foo: string, bar: number }

type VariantRec<T> = {[K in keyof T]: { type: K, value: T[K] }}
type Alpha1 = VariantRec<Eg>[keyof Eg]

type VariantType<T> = VariantRec<T>[keyof T]
type Alpha2 = VariantType<Eg>

const assignable12: Alpha2 = null as Alpha1
const assignable21: Alpha1 = null as Alpha2

Expected behavior:

Types Alpha1 and Alpha2 should be the identical.

Actual behavior:

Alpha2 incorrectly becomes: { type: 'foo' | 'bar', value: string | number }
It should be: { type: 'foo', value: string } | { type: 'bar', value: number }

@KiaraGrouwstra
Copy link
Contributor

Interesting. I'd posted a similar issue at #16244.

@KiaraGrouwstra
Copy link
Contributor

Hey, we found a solution for mine by separating the steps using generic defaults; still kinda feels like a bug, but I think a workaround like that may solve your case too! 😃

@liam-goodacre-hpe
Copy link
Author

@tycho01 Awesome, thanks! That appears to work 😸 Here's an updated playground.

@KiaraGrouwstra
Copy link
Contributor

Coming over from #16244, I just ran into another one super similar to yours, though here it doesn't seem fixable by defaults:

type Inc = [1, 2, 3, 4, 5];
type ObjectHasKey<O extends {}, K extends string> = ({[K in keyof O]: '1' } & { [k: string]: '0' })[K];
type Length<R extends {}, I extends number = 0> = { 1: Length<R, Inc[I]>, 0: I }[ObjectHasKey<R, I>];
type TestLenA = Length<{ 0: 'a', 1: 'b' }>;
// ^ ok, 2
type Wrap<O> = Length<O>;
// type Wrap<O, Len extends Length<O> = Length<O>> = Len;
// ^ old work-around, same result here
type TestLenB = Wrap<{ 0: 'a', 1: 'b' }>;
// ^ 0 :(

With the wrap wording I'm a bit reminded of #10247, though that concerned wrapping generic functions, while this is wrapping a generic type. Unfortunately, while in that other case one could observe the degenerating generics in the transformed output function, over here the inner workings feel somewhat opaque...

@mhegazy
Copy link
Contributor

mhegazy commented Aug 23, 2017

seems like a duplicate of #15756

@mhegazy mhegazy added the Duplicate An existing issue was already created label Aug 23, 2017
@KiaraGrouwstra
Copy link
Contributor

Fixed by #18042.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 8, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed Sep 8, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants