-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Using 'Key in keyof ArrayType' always returns an Array regardles of the value manipulation applied #40069
Comments
This working as intended. Mapped arrays/tuples stay arrays/tuples as of TypeScript 3.1. See #26063. |
I would argue that mapping its method & length keys to While it does work in accordance of the mentiond PR, this should then be considered a design oversight. ForReference: Playground Link type Values<T> = T[keyof T]
type ReduceToUnique<T> = { [P in keyof T]: T[P] extends typeof Unique ? 'this was unique' : never }
const Unique = Symbol("i'm unique")
// 6 different Types, all of them extend `object`
declare const objectType: object
declare const anyType: any
declare const notUniqueable: {someKey: 'someValue'}
declare const isUniqueable: {someKey: typeof Unique}
declare const notUniqueableArray: [1, 2, 3, 4, 5, 6, 7]
declare const isUniqueableArray: [1, 2, 3, 4, 5, 6, typeof Unique]
// a function that takes a generic `T extends object`
declare function reduceToUniqueKV <T extends object>(someObject: T): ReduceToUnique<T>
// the 6 Types processed by that function
const objectT = reduceToUniqueKV(objectType)
// ^-> object
const anyT = reduceToUniqueKV(anyType)
// ^-> ReduceToUnique<any>
const notU = reduceToUniqueKV(notUniqueable)
// ^-> ReduceToUnique<{ someKey: 'someValue'; }>
const isU = reduceToUniqueKV(isUniqueable)
// ^-> ReduceToUnique<{ someKey: typeof Unique; }>
const notUArr = reduceToUniqueKV(notUniqueableArray)
// ^-> [never, never, never, never, never, never, never]
const isUArr= reduceToUniqueKV(isUniqueableArray)
// ^-> [never, never, never, never, never, never, "this was unique"]
// reducing the results to their property values
declare const objectTValues: Values<typeof objectT>
// ^-> never
declare const anyTValues: Values<typeof anyT>
// ^-> 'this was unique'
declare const notUValues: Values<typeof notU>
// ^-> never
declare const isUValues: Values<typeof isU>
// ^-> 'this was unique'
declare const notUArrValues: Values<typeof notUArr>
// ^-> 7 | (() => string) | (() => string) | (() => undefined)
// | ((...items: never[]) => number)
// | { (...items: ConcatArray<never>[]): never[];
// (...items: ConcatArray<never>[]): never[]; }
// | ... 22 more ... | { ...; }
declare const isUArrValues: Values<typeof isUArr>
// ^-> 7 | "this was unique" | (() => string) | (() => string)
// | (() => "this was unique" | undefined)
// | ((...items: "this was unique"[]) => number)
// | { (...items: ConcatArray<"this was unique">[]): "this was unique"[];
// (...items: ("this was unique" | ConcatArray<...>)[]): "this was unique"[]; }
// | ... 22 more ... | { ...; } |
A mapped type will not touch type ToNevers<T> = { [K in keyof T]: never };
type A = ToNevers<string[]>['length']; // still number, not never The problem is you can't do type Values<T> = T extends unknown[] ? T[number] : T[keyof T]; |
@yume-chan completly missed this response, so my apologies for the late reply
Sure, this is easy when you expect an array, but if you just expect any generic object, this will really suprise you, see the example in my comment. Arrays have to be explicitly filtered out and handled differently (which i started doing after i ran into this). But this also has become much less of an issue with some of the awedome new features #40336 |
TypeScript Version: 4.0.0-beta (same behaviour in version 3.5.1 v3.5.1-Play Ground)
Search Terms:
"key in keyof Array", "keyof Array"
Expected behavior:
using
key in ArrayType
has the same behaviour as on any object (returning an array type only if the relevant properties are unchanged)Actual behavior:
using
key in ArrayType
performs actions on touple entries but the returned type allways includes all default Array propertiesExtention note:
Not the point of this issue and i know there are other issues around this topic. it's just a note,
but how about possibly adding tupple functionality for ArrayLike-, Map- and Set-types? They have all the basic qualities of a tupple, and it would be awesome to use them in a similar fashion (especially inference of
Map.prototype.get/set
and[Symbol.iterator]
inference of tupples)Related Issues:
#39726
#34780
type-fest/issues/119 (external library, but about this this behaviour and includes adHoc fix)
Code
infered types:
Output
Compiler Options
Playground Link: Provided
The text was updated successfully, but these errors were encountered: