Búsqueda de sitios web

react native - TypeScript no lanza errores cuando se pasa un valor no válido a las Props


const enum ColumnValues {
  one = 1,
  two = 2,
  three = 3,
}

interface Props {
  style?: StyleProp<ViewStyle>;
  title?: string;
  titleContainerStyle?: StyleProp<ViewStyle>;
  titleStyle?: StyleProp<TextStyle>;
  textInputStyle?: StyleProp<TextStyle>;
  column?: ColumnValues.one | ColumnValues.two | ColumnValues.three;
}

const DynPut: FC<Props> = Props => {
...
return(
...
)

He importado este DynPut en otro componente y he pasado el valor 10 a la propiedad Column, pero TypeScript no está generando ningún error. ¿Cómo hacer que TypeScript genere un error cuando se pase cualquier valor mayor que 3 a la propiedad Column?

  <DynPut
    title="Add Items"
    style={{backgroundColor: 'yellow'}}
    titleStyle={{backgroundColor: 'green'}}
    titleContainerStyle={{backgroundColor: 'green'}}
    textInputStyle={{borderWidth: 5}}
    column={10}
  />

Respuesta #1

Este es un problema muy similar a este, sin embargo la respuesta anterior debería modificarse ligeramente para ajustarse a este problema. Si piensas que es un duplicado, siéntete libre de marcarlo.

El problema principal aquí es que el tipo number en TypeScript se puede asignar a un enum numérico incluso si no cumple con los valores/requisitos del enum. Por favor, consulte esta respuesta para obtener más contexto.

Para validar el número proporcionado, necesitamos convertir en cadena todos los números del enum y el número de column proporcionado. Luego es seguro validarlos.

Considera este ejemplo:

enum ColumnValues {
    one = 1,
    two = 2,
    three = 3,
}

// Stringifies each enum numeric value. 
// Example: 3 -> "3"
type Enumerate<Enum> = Enum extends number | string ? keyof {
    [Prop in `${Enum}`]: Prop
} : never

// Obtain stringified enum values
type Result = Enumerate<ColumnValues> // "0" | "1"

// Obtain a union of object values
type Values<T> = T[keyof T]

// Check whether provided initial value extends stringifiedn enum value
// if yes - allow this value and return initial
// id no - return never, so TS with throe an error
type IsKeyValid<InitialValue extends number, Enum> =
    `${InitialValue}` extends Enumerate<Enum> ? InitialValue : never

type Props<Count extends number> = {
    column: IsKeyValid<Count, ColumnValues>
}
const DynPut = <Count extends number>(props: Props<Count>) => { }

DynPut({ column: 1 }) // ok
DynPut({ column: 5 }) // error

Parque infantil

Por favor, también vea mi artículo