microsoft / microsoft/TypeScript
Using 'Key in keyof ArrayType' always returns an Array regardles of the value manipulation applied
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
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 properties
Extention 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
type Arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
type Arr2 = (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9)[]
type WhoopMyArray_Faulty<Base extends ArrayLike<any>, Condition> = {
[Key in keyof Base]:
Base[Key] extends Condition
? 'Whoop it'
: Base[Key] extends Base[number] ? Base[Key] : never
}
// action is performed on array elements but return type is still a proper array
type WhoopedArray = WhoopMyArray_Faulty<Arr, 7 | 5 | 2>
type WhoopedArrayKeys = WhoopMyArray_Faulty<Arr, 7 | 5 | 2>[keyof Arr]
// related side note, but not the main pont
// no action performed. in line with 1st example, expected: (0 | 1 | 'Whoop it' | 3 | 4 | 'Whoop it' | 6 | 'Whoop it' | 8 | 9)[]
type WhoopedArray2 = WhoopMyArray_Faulty<Arr2, 7 | 5 | 2>
type WhoopedArray2Keys = WhoopMyArray_Faulty<Arr, 7 | 5 | 2>[keyof Arr]
infered types:
type WhoopedArray = [0, 1, "Whoop it", 3, 4, "Whoop it", 6, "Whoop it", 8, 9]
type WhoopedArrayKeys = 0 | "Whoop it" | 1 | 3 | 4 | 6 | 8 | 9 | 10 | (() => string) | (() => string)
| (() => 0 | "Whoop it" | 1 | 3 | 4 | 6 | 8 | 9 | undefined) | ((...items: (0 | "Whoop it" | 1 | 3 | 4 | 6 | 8 | 9)[]) => number)
| { ...; } | ... 22 more ... | (() => IterableIterator<...>)
type WhoopedArray2 = (0 | 7 | 5 | 2 | 1 | 3 | 4 | 6 | 8 | 9)[]
type WhoopedArray2Keys = 0 | "Whoop it" | 1 | 3 | 4 | 6 | 8 | 9 | 10 | (() => string) | (() => string)
| (() => 0 | "Whoop it" | 1 | 3 | 4 | 6 | 8 | 9 | undefined) | ((...items: (0 | "Whoop it" | 1 | 3 | 4 | 6 | 8 | 9)[]) => number)
| { ...; } | ... 22 more ... | (() => IterableIterator<...>)
Output
"use strict";
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": true,
"alwaysStrict": true,
"allowUnusedLabels": true,
"noEmitHelpers": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"preserveConstEnums": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "Latest",
"module": "ESNext"
}
}
Playground Link: Provided
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided TypeScript Playground link and the mapped-type examples using keyof Array and tuple types. Compare the inferred types with the stated expected and actual behavior, then review related issues #39726 and #34780. Done means the mapped type preserves the intended tuple or array element transformations without unexpectedly including unchanged Array members.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100