ianstormtaylor / superstruct

A simple and composable way to validate data in JavaScript (and TypeScript).
https://docs.superstructjs.org
MIT License
6.96k stars 223 forks source link

Adding rest props for object-type #1162

Closed vtrushin closed 9 months ago

vtrushin commented 1 year ago

First of all, thank you for this convenient tree-shakeable lib!

Sometimes we don't need to know, what the keys are in our object, but only their types E.g. We keep addresses, added by user in structure like that:

addresses: {
  [addressName: string]: string
}

TS allows us to do it

What if to add similar behavior in object structure, using a Symbol for that. Symbol lets you distinguish this props from any others:

// Inside Superstruct lib
export const anyProp = Symbol()
...
const isAnyProp = key === anyProp
...

// On Superstruct's user side
import { object, anyProp } from 'superstruct'

const Addresses = object({
  requiredAddressField: string,
  [anyProp]: string
})
arturmuller commented 9 months ago

Hi @vtrushin!

It's been a while since you asked this question, but perhaps the answer might still be useful for you or others.

You should be able to achieve what you ask for with the existing features of superstruct:

// Just like in TS where you can describe your desired behaviour with an intersection of a
// type and a record:
type Addresses = { requiredAddressField: string } & Record<string, string>

// ...in Superstruct, you can do the same thing:
const addresses = intersection([
  type({ requiredAddressField: string() }),
  record(string(), string()),
]);

Note that it is important that you use type not object in this case, as object would not allow extraneous keys and validation would therefore not pass.


I will close this issue for now, but if there are some additional details you would like to discuss, feel free to comment!

vtrushin commented 9 months ago

@arturmuller Thank you for your answer!