Skip to content

Mapped array/tuple types can't be used as generic with a constraintΒ #48740

Closed
@Jamesernator

Description

@Jamesernator

Bug Report

πŸ”Ž Search Terms

mapped tuple type

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about mapped type

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

class ValType {
    #isValType = true;
}
class I32 extends ValType {
    #isI32 = true;
}
class Externref extends ValType {
    #isExternref = true;
}

class Local<T extends ValType> {
    readonly #type: T;

    constructor(type: T) {
        this.#type = type;
    }

    get type(): T {
        return this.#type;
    }
}

type LocalsFor<Type extends ReadonlyArray<ValType>> = {
    // Type 'Type[K]' does not satisfy the constraint 'ValType'.
    //   Type 'Type[keyof Type]' is not assignable to type 'ValType'.
    //     Type 'Type[string] | Type[number] | Type[symbol]' is not assignable to type 'ValType'.
    //       Type 'Type[string]' is not assignable to type 'ValType'.(2344)
    [K in keyof Type]: Local<Type[K]>
};

// This is still the correct type, because mapped array/tuples still
// just map their values despite the above error
const locals: LocalsFor<[I32, Externref]> = [
    new Local(new I32()),
    new Local(new Externref()),
];

πŸ™ Actual behavior

It produces an error in the mapped type that Type[K] doesn't satisfy the constraint.

πŸ™‚ Expected behavior

There should be no error, as mapped types do not map over all keys in the array/tuple, it should only consider Type[K] to be the numeric keys of the tuple, i.e. Type[K] in the mapped type will only ever be (subtypes of) ValType because ultimately K will only be assigned to the numeric keys of Type as it's an array type.

In this particular case, we have an explicit Type extends ReadonlyArray<ValType> so TypeScript should be able to deduce just fine that this particular mapped type will only ever be over an array, and hence should be able to deduce that Type[K] will only ever be Type[number] (or Type[`${ number }`] for tuples).

I had another issue, however I closed it and opened this one because this is likely the fundamental cause of both problems.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions