-
Notifications
You must be signed in to change notification settings - Fork 13k
Description
TypeScript Version: 3.5.0-dev.20190407
Search Terms:
record, Object.values
Code
interface onlyStrings extends Record<keyof onlyStrings, string> {
a: string;
b: string;
}
const b: onlyStrings = null;
Object.values(b); // any[]
Object.values<string>(b); // error, index signature is missing in onlyStrings
Expected behavior:
Object.values(object) for an object whose type extends Record<K,V> should return array with type V[]
Actual behavior:
Object.values(b)
as above returns any[]
, trying to specify values<string>
gives an error that onlyStrings
is missing index signature. Because it is extending a Record it should know the type for the returned values even without an index signature.
It does work when working with the Record type directly instead of extending, or when extending and including an index signature, or when the key type is explicit:
const a: Record<keyof onlyStrings, string> = null;
Object.values(a); // string[]
interface stringsWithIndexSignature extends onlyStrings {
[s: string]: string;
}
const c: stringsWithIndexSignature = null;
Object.values(c); // string[]
interface stringMap extends Record<string, string> {
a: string;
b: string;
}
const d: stringMap = null;
Object.values(d) // string[]
It can be made to work by wrapping in a function and specifying the generic types:
function typedValues<U, T extends Record<keyof T, U>>(recordObject: T): U[] {
return Object.values(recordObject);
}
typedValues(b); // {}[]
typedValues<string, onlyStrings>(b); // string[]
Playground Link: Object.values is not supported in TS Playground. I tried to reproduce with Object.keys().map()
but that returns any[]
regardless of original type.
Related Issues: possibly #26010 - Object.values and Object.entries return type any when passing an object defined as having number keys and #21089 - [TS2.5 regression] Object.values(someEnum) returns string[] (not any[]/number[])