¿Es posible especificar la longitud de la matriz que proviene de los props usando el tipo de Typescript ?
Tenemos una matriz de objetos:
const arrayPassedViaProps = [ { key: '1', label: 'Label 1', value: 9 }, { key: '2', label: 'Label 2', value: 3 }, { key: '3', label: 'Label 3', value: 3 }, { key: '4', label: 'Label 4', value: 22 }, { key: '5', label: 'Label 5', value: 1 } ] Paso esta matriz como props como este:
<DownlineProgress data={arrayPassedViaProps} /> Dentro del componente DownlineProgress un tipo:
type DownlineProgressBarProps = { data: { key: string label: string value: number }[] } Estoy usando este tipo con props
export const DownlineProgress = ({data}: DownlineProgressBarProps) => ...Me gustaría que Typescript me informe cuando pase accesorios de que la matriz no tiene la longitud correcta, debe contener DOS o TRES objetos
¿Cómo puedo modificar mi type para lograr tal comportamiento?
PD. actualmente estoy usando la declaración if para verificar
if(data.length > 3 || data.length < 2){ throw(`DownlineProgress need an array of length 2 or 3. You pass ${data.length}`) }Aquí hay una solución pura de TypeScript:
interface Data { key: string; label: string; value: number; } // The following type should have two or three elements of type Data type ArrayWithTwoOrThreeDataElements = [ Data, Data, Data? ]; En su caso, dado que en el valor de accesorios espera un objeto con una propiedad llamada data de tipo Datos, puede definir el tipo de accesorios de la siguiente manera:
type DownlineProgressBarProps = [ { data: Data }, { data: Data }, { data: Data }? ];Naturalmente, puede crear un tipo para un solo elemento de utilería si desea evitar repetir la clave de propiedad de datos :
interface Data { key: string; label: string; value: number; } interface DownlineProgressBarProp { data: Data } type DownlineProgressBarProps = [ DownlineProgressBarProp, DownlineProgressBarProp, DownlineProgressBarProp? ];Puede especificar la longitud de una matriz con estos tipos personalizados :
type TupleOf<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never; type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;Y entonces:
type DownlineProgressBarProps = { data: TupleOf<{ key: string label: string value: number }, 2 | 3> }Puede crear una función personalizada para la misma sería la forma correcta.
const propTypes = { data: arrayOfLength.bind(null, 2) } const arrayOfLength = (expectedLength, props, propName, componentName) => { const arrayPropLength = props[propName].length if (arrayPropLength !== expectedLength) { return new Error( `Invalid array length ${arrayPropLength} (expected ${expectedLength}) for prop ${propName} supplied to ${componentName}. Validation failed.` ) } }