TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

`keyof Readonly<string[]>` different from `keyof Readonly<T>` where T is string[]

Open miguel-leon opened this issue 1 year ago • 1 comments

🔎 Search Terms

keyof Readonly array

🕗 Version & Regression Information

Latest to date

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAKgjFAvFAShAhgEwPYDsA2IAPAM7ABOAlrgOYDaAugHwDcUA9O1ORjgSFDJVajALAAoUJFQJkAawghsAM1hw2nKAqWqeWPIUEVq9BhIlToAaUUB5ZWn38iMJki2KVqXgeKuWFuDQKABM7jYg9o58hKTGIswaXIAy5B46RsKmEkA

💻 Code

type T1 = Readonly<string[]>; // readonly string[]
type R1 = keyof T1; // keyof readonly string[]

type KeyOfReadonly<T> = keyof Readonly<T>;
type R2 = KeyOfReadonly<string[]>; // ❌ keyof string[]

🙁 Actual behavior

doesn't work

🙂 Expected behavior

works

Additional information about the issue

What can I say, I really hope this is not the intended behavior.

miguel-leon avatar Oct 15 '24 07:10 miguel-leon

This issue arises from how TypeScript infers generic types and handles them in different contexts.

Use a Conditional Type to Handle the Array Type Separately

type KeyOfReadonly<T> = T extends any[] ? keyof Readonly<T> : keyof T;

This ensures that if T is an array (like string[]), it will still behave as you expect for keyof Readonly<string[]>

mudassir-jmi avatar Oct 15 '24 13:10 mudassir-jmi