Skip to content
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

Objects with unknown property names #43

Closed
b-zurg opened this issue Jul 10, 2020 · 10 comments
Closed

Objects with unknown property names #43

b-zurg opened this issue Jul 10, 2020 · 10 comments
Labels
enhancement New feature or request

Comments

@b-zurg
Copy link

b-zurg commented Jul 10, 2020

Very often I'll encounter situations where I need to type an object that has unknown property names (e.g. an id or a key) but the shape of its value is known.

e.g.

type Point = { x: number; y: number};
interface PointMap {
  [key: string]: Point;
}

I can't really figure out how to accomplish that with computed-types.

@moshest
Copy link
Member

moshest commented Jul 12, 2020

Hi, thanks for bring this up!

I still didn't have the time to look into it, I think the best solution will be to implement some Record<K, V> validator to solve it.
If this urgent, you can always create your own validator like this:

const PointSchema = Schema({ x: number, y: number });

const PointMapSchema = object.test((obj) => Object.values(obj).every(PointSchema));

@b-zurg
Copy link
Author

b-zurg commented Jul 12, 2020

Thanks for responding! It's not urgent but good to know about the example you provided! Having some sort of Record<K, V> seems perfect.

@moshest moshest added the enhancement New feature or request label Jul 15, 2020
@moshest moshest added this to the v1.2 milestone Jul 21, 2020
@moshest
Copy link
Member

moshest commented Aug 2, 2020

Proposed interface:

import { Record, string, number } from 'computed-types';

const PointMap = Record(string, { x: number, y: number });

@b-zurg
Copy link
Author

b-zurg commented Aug 3, 2020

In a Record<K,V> approach I guess the only valid index types for K would be a string or string union. The V however could be any valid schema. The above example is an inline schema definition I'm guessing but it would be nice to be able to also provide schemas defined elsewhere.

@moshest
Copy link
Member

moshest commented Aug 3, 2020

The key validator will be any value that can as as an object property (number, string or symbol). You will be able to provide any validator such as: Schema.enum(MyKeys), Schema.either('foo', 'bar') etc..

@moshest moshest removed this from the v1.2 milestone Oct 7, 2020
@bradenmacdonald
Copy link

bradenmacdonald commented Jun 27, 2021

Hi, here is a generic version that I created today, which seems to work well and will also create the correct Record<K, V> TypeScript type when used with Type<>.

type Validator<T> = (value: any) => T;  // I can't find if/where this type is exported from computed_types?

export const Record = <KeyType extends string | number | symbol, ValueType>(keySchema: Validator<KeyType>, valueSchema: Validator<ValueType>) => {
    return (object
        .test((obj) => Object.values(obj).every(valueSchema) && Object.keys(obj).every(keySchema))
        .transform(obj => obj as Record<KeyType, ValueType>)
    );
}

Screen Shot 2021-06-27 at 2 37 19 PM

You will be able to provide any validator such as: Schema.enum(MyKeys), Schema.either('foo', 'bar') etc..

Yep, that is working.

@marcelbeumer
Copy link

Are there plans to release this?

@moshest
Copy link
Member

moshest commented Oct 21, 2021

I don't have the time right now. You're welcome to create a PR.

@moshest
Copy link
Member

moshest commented Oct 21, 2021

Released in v1.11.0

@moshest moshest closed this as completed Oct 21, 2021
@marcelbeumer
Copy link

Awesome, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants