`size` on `array` uses a permissive type
shellscape opened this issue · comments
Andrew Powell commented
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
.