ianstormtaylor / superstruct

A simple and composable way to validate data in JavaScript (and TypeScript).

Home Page:https://docs.superstructjs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`size` on `array` uses a permissive type

shellscape opened this issue · comments

Consider the following:

const ActionWildcardStruct = size(array(literal('*')), 1);
export type ActionWildcard = Infer<typeof ActionWildcardStruct>;

That Infer produces a type of type ActionWildcard = "*"[]. While that's correct, it's overly permissive given the size constraints. Instead, we could use something like this:

// Lifted from: https://stackoverflow.com/questions/41139763/how-to-declare-a-fixed-length-array-in-typescript
type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift' | number;
type ArrayItems<T extends any[]> = T extends Array<infer TItems> ? TItems : never;
type FixedLengthArray<T extends any[]> = Pick<T, Exclude<keyof T, ArrayLengthMutationKeys>> & {
  [Symbol.iterator]: () => IterableIterator<ArrayItems<T>>;
};

And the Infer result could then be:

type ActionWildcard = FixedLengthArray<['*']>

That would be much more restrictive and true to the intent of the use of size.