reactjs - Permitir objeto temporalmente vacío para un estado tipado
Vengo de un entorno de JS y ahora estoy aprendiendo Typescript. No puedo superar este problema. Tengo un estado muy específicamente tipado que sé que necesitaré en el futuro para trabajar con él:
type NotificationValuesType = {
channel: string
for: NotificationUsageTypes
id: string
type: NotificationTypes
workspace: string
}[]
Estoy configurando mi estado de React así:
const [dropdownsState, setDropdownsState] = useState<NotificationValuesType>([])
La cuestión es que inicialmente ahora solo puedo type e id, todas las demás propiedades puedo recopilarlas a través de una serie de menús desplegables cuando un usuario los elige, se dispara un evento y luego se llena el estado con un menú desplegable a la vez, así que en algún punto, será solo: [{id: "id", type: "type", channel: "channel"}] en el siguiente evento, será [{id: "id", type: "type", channel: "channel", workspace: "workspace"}] y un paso más y actualización del estado para conocer todas las propiedades en el tipo declarado.
Lo que no entiendo es cómo decirle a Typescript que deje de gritarme hasta el momento en que conozca todas las props y asegurarme de que conoceré todas las props necesarias en el futuro.
- Absolutamente no puedo hacer que ninguno de estos props sea opcional porque no
son opcionales. - También intenté establecer el tipo de estado en
NotificationValuesType | [], pero TypeScript sigue gritando - Aprendí sobre las afirmaciones de tipo y supongo que deberían ayudar, pero no puedo encontrar ningún ejemplo de cómo usarlas en el estado. ¿Puedo hacer algo como
const [dropdownsState, setDropdownsState]=useState as <NotificationValuesType>([])???
¡Gracias por leer hasta el final! =)
Respuesta #1
Absolutamente no puedo hacer que ninguno de estos props sea opcional porque no son opcionales.
Quizás no cuando hayas terminado, pero mientras estás en el proceso de construirlo, si los valores necesitan ser undefined, entonces el tipo necesita reflejar eso. Así que lo más probable es que quieras que la variable de estado tenga propiedades opcionales, luego sigues tus pasos para completarla, y una vez que hayas verificado que todo está allí, puedes asignarla a una variable con un tipo donde todas las propiedades son obligatorias.
Hay un tipo auxiliar llamado Partial que tomará un tipo y producirá uno nuevo cuyas propiedades son opcionales.
// Note: this type is just the individual object, not the array that you have
type Example = {
channel: string
for: NotificationUsageTypes
id: string
type: NotificationTypes
workspace: string
}
const [dropdownsState, setDropdownsState] = useState<Partial<Example>[]>([])
// Later on, once you've verified that all the properties exist you can
// assert that it's done. I don't know exactly what your verification
// code will look like, but here's an example
if (dropdownsState.every(value => {
return value.channel && value.for && value.id && value.type && value.workspace
})) {
const finishedState = dropdownsState as Example[];
// do something with the finished state
}
EDIT: como se señaló en los comentarios, si usas un guardia de tipo, entonces TypeScript puede reducir los tipos y ahorrarte tener que reasignarlo:
if (dropdownsState.every((value): value is Example => {
return value.channel && value.for && value.id && value.type && value.workspace
})) {
// Inside this block, typescript knows that dropdownsState is an Example[]
}
