piotrwitek / utility-types

Collection of utility types, complementing TypeScript built-in mapped types and aliases (think "lodash" for static types).
MIT License
5.54k stars 230 forks source link

$ElementType does not work with keyofStringsOnly TS option #179

Open Knagis opened 2 years ago

Knagis commented 2 years ago

Description

export declare type $ElementType<T extends {
    [P in K & any]: any;
}, K extends keyof T | number> = T[K];

with keyofStringsOnly: true

Type 'K' cannot be used to index type 'T'.(2536)

Steps to Reproduce

open https://www.typescriptlang.org/play?keyofStringsOnly=true&ssl=3&ssc=39&pln=1&pc=1#code/KYDwDg9gTgLgBAE2AYwDYEMrDjAnmbAEgFFVgBbYAOxgBV9gAeWuUGahAZzgG8AoOILgBtAApwAllTgBpOADI46KrgC6ALiUqA3HwC+AGlmsQ7KlzgBrYLggAzOCwA+cKgFdyAI2BQAfHABeR2EZVV0BQQB6SLhicBQYTU4YKCkAc10hPAI4USgIMG4gnld0SiSU9O0lNOBNdy8faoA3CU4JTzJNTwgIMmU4PUzBbOwAOTLgehygkjJKGmmmPILOIwByKkn133ChaNj45ES4Hr7gZQicBkc3MDJAkTP+qiMG7ygwq9G4AEFHuYUah0BjMO5kDYABh2wzgBziBGO9Q8H2+NwAQgDSEDFqDaODgBsAIwwvhXeFHE7PC5UNE5X5QKCPanKYRfLI3ACS7HInCWWPmwKWjAZUDeKJ8uzJ+xiCISyMaUDp2AA8p4AFaPErCay4CqpKhpDSuCVMobKuAANXQqDcwD5N1m2IWIIIjDV6qMyQNaSlQA

Expected behavior

no TS compilation errors

Suggested solution(s)

export declare type $ElementType<T extends {
    [P in K & any]: any;
}, K extends keyof T | number> = T extends [] ? T[K] : T[Exclude<K, number>];

this passes the examples given in the file for both when keyofStringsOnly is enabled and disabled.

Project Dependencies

Knagis commented 2 years ago

slightly better approach, does not exclude number when keyof T does include it:

export declare type $ElementType<T extends {
    [P in K & any]: any;
}, K extends keyof T | number> = T extends [] ? T[K] : T[Exclude<K, Exclude<number, keyof any>>];
piotrwitek commented 2 years ago

Hey @Knagis , thanks for the report and solution, could you please submit a PR?