Quiero tener un objeto que pueda contener cadenas o una matriz de cadenas. Todo con una llave de cadena. Este es un objeto de configuración que se usará en una aplicación.
Este objeto será dinámico (valores de estado definidos por el usuario), por lo que no tengo forma de especificar tipos según el nombre de clave específico. Es por eso que estoy usando firmas de índice ya que no sé cuáles serán las claves. Agregaré matrices de una parte de mi aplicación y cadenas de otra parte.
Estoy recibiendo errores como se ve a continuación:
type FiltersStateType = { filters: { [key: string]: Array<string> | string } } const example: FiltersStateType = { filters: { sandwiches: ['ham', 'cheese'], milkshakes: ['choc', 'banana'], randomString: 'hello', }, } example.filters.sandwiches.filter(item => item !== 'ham') // ❌ Property 'filter' does not exist on type 'string | string[]'. // ❌ Property 'filter' does not exist on type 'string' // do I need to type narrow every time to discern between string and string[]? if (Array.isArray(example.filters.sandwiches)) { example.filters.sandwiches.filter(item => item !== 'ham') }Supongo que esto se debe a que TS no sabe si es una cadena o una matriz. ¿Necesito escribir estrecho cada vez para distinguir entre cadena y cadena []?
if (Array.isArray(example.filters.sandwiches)) { example.filters.sandwiches.filter(item => item !== 'ham') }Puedo recomendarte que uses este ejemplo. La línea [key: string]: Array<string> | string; es para futuras propiedades que se pueden agregar en el futuro. Después de enumerar las propiedades de necesidad y sus tipos. El problema principal es que no puede combinar varios tipos y luego acceder a la propiedad que no está incluida en ninguno de los dos tipos. Por ejemplo, no enumeré la propiedad randomString , pero puedo acceder fácilmente a su n-ésimo elemento porque tanto la array como la string tienen esta propiedad.
type FiltersStateType = { filters: { [key: string]: Array<string> | string; sandwiches: string[]; milkshakes: string[]; } } const example: FiltersStateType = { filters: { sandwiches: ['ham', 'cheese'], milkshakes: ['choc', 'banana'], randomString: 'hello', }, } example.filters.sandwiches = example.filters.sandwiches.filter(item => item !== 'ham') console.log(example.filters.sandwiches); console.log(example.filters.randomString[1]); O puede usar as palabra clave:
type FiltersStateType = { filters: { [key: string]: Array<string> | string; } } const example: FiltersStateType = { filters: { sandwiches: ['ham', 'cheese'], milkshakes: ['choc', 'banana'], randomString: 'hello', }, } example.filters.sandwiches = (example.filters.sandwiches as string[]).filter(item => item !== 'ham') console.log(example.filters.sandwiches); console.log(example.filters.randomString[1]); Lo siento en SO Code Snippet No puedo ejecutar debido a as string[]