Giter VIP home page Giter VIP logo

Comments (3)

sinclairzx81 avatar sinclairzx81 commented on July 2, 2024 1

@sdeprez Hi!

But maybe we can at least improve the type {} for Type.object({}), which is arguably wrong because it allows any non-null values? It could use object for instance so at least it would only allow real objects, and not other primitive values, which is consistent with the generated json schema.

Yeah, let me have a think about this. I think if making changes to TObject inference, I'd want to factor the additionalProperties in that inference. Similarly based on #889, I think there is also a case to consider factoring unevaluatedProperties in inference too (where this issue highlights some of the cross over between inference, types and runtime assertion logic).

Ill add a consideration tag to this issue and take a technical deep dive on it next time I get to sit down with the code. However given the complexity and general changes required, I wouldn't expect this functionality to land until the next minor revision (scheduled later on this year), but will see how things go.

Will keep you posted!
S

from typebox.

sinclairzx81 avatar sinclairzx81 commented on July 2, 2024

@sdeprez Hi,

In that case, the type of T is {}, which in Typescript actually validates every non-null values, so the following assignments are all valid:

This is somewhat intentional (and partially historical) but mostly a consequence of TObject types not factoring additionalProperties constraints in inference (although the permissible number and string assignments are unfortunate). I think to provide better inference here, TObject should infer as one of the following depending on the whether additionalProperties has been specified.

For example, consider the following (where an empty object without constraints is permissible of additional properties)

const T = Type.Object({})                                          // type T = Record<PropertyKey, unknown>

const S = Type.Object({}, { additionalProperties: false })         // type T = Record<PropertyKey, never>

const U = Type.Object({}, { additionalProperties: Type.Number() }) // type T = Record<PropertyKey, number>

Unfortunately, this leads to some fairly awkward scenarios.

const T = Type.Object({
    x: Type.String(),
    y: Type.String(),
    z: Type.String(),
}, {
    additionalProperties: Type.Number()
})

type T = Record<PropertyKey, number> & {
    x: string,
    y: string,
    z: string
}

const a: T = { // error unassignable: property values of string
    x: '1',    // are not number
    y: '2',
    z: '3'
}

Do you have any thoughts or suggestions regarding the appropriate inference when factoring the above additional Property constraints? Open to discussion on this.

Cheers
S

from typebox.

sdeprez avatar sdeprez commented on July 2, 2024

Thanks for your detailed response!

I agree that if we factor additionalProperties, it gets more complex 🤔 . But maybe we can at least improve the type {} for Type.object({}), which is arguably wrong because it allows any non-null values? It could use object for instance so at least it would only allow real objects, and not other primitive values, which is consistent with the generated json schema.

For the record, I'm using this great library ;) typebox inside fastify and I'm using Static to extract types from my serializers. I tripped over this issue here when I wondered when one route handler that was returning a boolean did not make the typecheck fail. So I would be happy with an object type instead, and it wouldn't check for additional properties but that's consistent with the other types from what I understand, and unwanted properties would be removed by the serializer anyway.

from typebox.

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.