Skip to content

Object.values doesn't infer type when extending Record type #30805

@Krumpet

Description

@Krumpet

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[])

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions