-
Notifications
You must be signed in to change notification settings - Fork 12.2k
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
Object.values doesn't infer type when extending Record type #30805
Comments
Strongly typing |
What about my last example, where subtyping does give the right type? Wouldn't it be wrong to return interface stringMap extends Record<string, string> {
a: string;
b: string;
}
const d: stringMap = null;
Object.values(d) // string[] Another question - how can Thanks for the feedback! |
type Point2D = Record<"x" | "y", number>;
function fn(obj: Point2D) {
console.log(Object.values(obj).some(v => typeof v !== "number"));
}
const NamedPoint = { x: 0, y: 0, name: "origin" };
fn(NamedPoint); |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
I understand the concern, but it would be nice to be able to provide some ability to have types that can convey the completeness of the object for these iterators. Iran into an issue like this: type SetData = { foo: string }
type UnionSet<Keys extends string> = { [K in Keys]: SetData }
function handleGenericSet<T extends string>(set: UnionSet<T>) {
const entries = Object.entries(set) // const entries: [string, unknown][] expect [string, SetData][]
const values = Object.values(set) // const values: unknown[] expect SetData[]
const keys = Object.keys(set) // const keys: string[] expect T
}
type MyUnion = 'a' | 'b' | 'c'
function handleSpecificSet(set: UnionSet<MyUnion>) {
const entries = Object.entries(set) // const entries: [string, SetData][] expect [string, SetData][]
const values = Object.values(set) // const values: unknown[] expect SetData[]
const keys = Object.keys(set) // const keys: string[] expect MyUnion
} |
While the trick of inheriting from interface Interface {
a: string
b: string
}
const x: Interface = Object.freeze({a: "a", b: "b"})
// or nicer but maybe confusing? Kinda like readonly arrays/tuples:
// const x: readonly Interface = {a: "a", b: "b"}
const y = Object.values(x) |
TypeScript Version: 3.5.0-dev.20190407
Search Terms:
record, Object.values
Code
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 returnsany[]
, trying to specifyvalues<string>
gives an error thatonlyStrings
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:
It can be made to work by wrapping in a function and specifying the generic types:
Playground Link: Object.values is not supported in TS Playground. I tried to reproduce with
Object.keys().map()
but that returnsany[]
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[])
The text was updated successfully, but these errors were encountered: