Code Monkey home page Code Monkey logo

Comments (12)

fatcerberus avatar fatcerberus commented on May 16, 2024 1

@typeholes Just to be clear: From the type checker's point of view there's no difference between the explicitly typed o in your example and the explicitly typed i in Martin's. Returning (string | null)[] when Object.values is called on an I wouldn't be sound.

from typescript.

MartinJohns avatar MartinJohns commented on May 16, 2024

This is working as intended.

This is perfectly legal code, and a return type of (string | null)[] would be wrong:

const o = { foo: 123, 5: 'test', 8: null };
const i: I = o;

from typescript.

nmain avatar nmain commented on May 16, 2024

See this FAQ entry: https://github.com/microsoft/TypeScript/wiki/FAQ#indirect-excess-properties-are-ok

from typescript.

typeholes avatar typeholes commented on May 16, 2024

Scratch that, I see the issue and it should really be returning unknown[]

I understand how that FAQ applies to Object.keys, but I do not think it applies here.

const o = { foo: 123, 5: 'test', 8: null };
const i: I = o;

Here you have explicitly type i: I so I would expect that Object.values would return I[string|number][] (edit: per fatCerebus's correction)

note that if you let i be inferred the result would be (string | number | null)[] which is also correct

from typescript.

fatcerberus avatar fatcerberus commented on May 16, 2024

Why would Object.values(i) return I[]? None of the properties are Is. The point Martin is making is that TS is only seeing the types here and there's no guarantee that a thing typed as I only has string | null values.

from typescript.

MartinJohns avatar MartinJohns commented on May 16, 2024

Scratch that, I see the issue and it should really be returning unknown[]

Agreed, but that would be a very big breaking change for little gain.

Here you have explicitly type i:

That was intentional to demonstrate the point. You don't know where and how the object was created.

from typescript.

typeholes avatar typeholes commented on May 16, 2024

Interestingly we have the exact same issue with a record, but do get the specific result type

type T = Record<number, string|null>
interface I { [x: number]: string | null ; } 

const o = { foo: 123, 5: 'test', 8: null };
const oT: T = o; const ovT = Object.values(oT);  // (string | null)[]
const oI: I = o; const ovI = Object.values(oI);  // any[]

https://www.typescriptlang.org/play/?target=99&jsx=0&exactOptionalPropertyTypes=true&lib=lib.esnext.d.ts&ts=5.5.0-dev.20240429#code/PTAEAEBcEMCcHMCmkBcpEGcB2iAekAoECAGwEsAjNTHfAgsrSRWAM2gGNFQBJUAb1ABtXGiwBXALYUWAXTQZIsRvFAAfUBJIlQAblABfUPUgBPAA7cAKqAC8oAEqIOAe1gATADwTpLADSgispY8GpaJAB89K5YiqAudgKgrC4uaACMAEwAzAEArGgA5MyKhQEAHGLi2oa6BDFxLlZoNvYu+g2Q8QBuraAA8hQAVs6QAHTd0CTimAAUTQCU+qDEs0Eq6prVJAtCskRgoEfHJ6enAHoA-PUusV0uPGh8bR23jd3PA8OjE1MzGPMeEsjsRoFhTHsDmdoTCrvQCEA

from typescript.

snarbies avatar snarbies commented on May 16, 2024

Object.values has an overload for array-likes and string index signatures (but not bare numeric index signatures).

    values<T>(o: { [s: string]: T; } | ArrayLike<T>): T[];

Supporting arrays makes sense. I'm guessing the string index signature is meant for object-as-a-dictionary scenarios. Either one has a potential hazard with excess properties, though.

from typescript.

typeholes avatar typeholes commented on May 16, 2024

Correct, so my question is should we be inconsistent between the interface and record values. I think consistency would be better, especially when you consider that any is just explicitly unsound.

from typescript.

snarbies avatar snarbies commented on May 16, 2024

It's not really inconsistent though. Index signatures and interfaces represent different things.

Index signatures are "arrayish." They may not necessarily have numeric keys, but they represent collections of key/value pairs where the "element" values all conform to a single type, so it makes sense for Object.values to support this scenario.

By its very nature, an interface is not exhaustive. An interface represents a subset of an object's actual shape (or a commonality among otherwise differently-shaped objects). So even if Object.values returned a union of known property types based on the interface, you would still have to include unknown in the union to account for properties not identified by the interface. And if you include unknown in the union, then the entire thing reduces to unknown.

That it returns any instead of unknown is unfortunate, but it's due to historical reasons.

from typescript.

typeholes avatar typeholes commented on May 16, 2024

Implementation is in #58358

from typescript.

typescript-bot avatar typescript-bot commented on May 16, 2024

This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

from typescript.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.