Skip to content

Indexing mapped type with keyof type param #16018

Closed
@liam-goodacre-hpe

Description

@liam-goodacre-hpe

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 }

Activity

KiaraGrouwstra

KiaraGrouwstra commented on Jun 9, 2017

@KiaraGrouwstra
Contributor

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

KiaraGrouwstra

KiaraGrouwstra commented on Jun 11, 2017

@KiaraGrouwstra
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

liam-goodacre-hpe commented on Jun 12, 2017

@liam-goodacre-hpe
Author

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

KiaraGrouwstra

KiaraGrouwstra commented on Jun 30, 2017

@KiaraGrouwstra
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

mhegazy commented on Aug 23, 2017

@mhegazy
Contributor

seems like a duplicate of #15756

KiaraGrouwstra

KiaraGrouwstra commented on Aug 25, 2017

@KiaraGrouwstra
Contributor

Fixed by #18042.

mhegazy

mhegazy commented on Sep 8, 2017

@mhegazy
Contributor

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

locked and limited conversation to collaborators on Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @KiaraGrouwstra@liam-goodacre-hpe@mhegazy

        Issue actions

          Indexing mapped type with keyof type param · Issue #16018 · microsoft/TypeScript