Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

1.4K
Vistas
El elemento tiene implícitamente un tipo 'cualquiera' porque la expresión de tipo 'cadena' no se puede usar para indexar

Probando TypeScript para un proyecto React y estoy atascado en este error:

 Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ train_1: boolean; train_2: boolean; train_3: boolean; train_4: boolean; }'. No index signature with a parameter of type 'string' was found on type '{ train_1: boolean; train_2: boolean; train_3: boolean; train_4: boolean; }'

Que aparece cuando trato de filtrar la matriz en mi componente

 .filter(({ name }) => plotOptions[name]);

Hasta ahora miré el artículo "Indización de objetos en TypeScript" ( https://dev.to/kingdaro/indexing-objects-in-typescript-1cgi ) ya que tenía un error similar, pero traté de agregar la firma de índice a escriba plotTypes y sigo recibiendo el mismo error.

Mi código de componente:

 import React, { Component } from "react"; import createPlotlyComponent from "react-plotly.js/factory"; import Plotly from "plotly.js-basic-dist"; const Plot = createPlotlyComponent(Plotly); interface IProps { data: any; } interface IState { [key: string]: plotTypes; plotOptions: plotTypes; } type plotTypes = { [key: string]: boolean; train_1: boolean; train_2: boolean; train_3: boolean; train_4: boolean; }; interface trainInfo { name: string; x: Array<number>; y: Array<number>; type: string; mode: string; } class FiltrationPlots extends Component<IProps, IState> { readonly state = { plotOptions: { train_1: true, train_2: true, train_3: true, train_4: true } }; render() { const { data } = this.props; const { plotOptions } = this.state; if (data.filtrationData) { const plotData: Array<trainInfo> = [ { name: "train_1", x: data.filtrationData.map((i: any) => i["1-CumVol"]), y: data.filtrationData.map((i: any) => i["1-PressureA"]), type: "scatter", mode: "lines" }, { name: "train_2", x: data.filtrationData.map((i: any) => i["2-CumVol"]), y: data.filtrationData.map((i: any) => i["2-PressureA"]), type: "scatter", mode: "lines" }, { name: "train_3", x: data.filtrationData.map((i: any) => i["3-CumVol"]), y: data.filtrationData.map((i: any) => i["3-PressureA"]), type: "scatter", mode: "lines" }, { name: "train_4", x: data.filtrationData.map((i: any) => i["4-CumVol"]), y: data.filtrationData.map((i: any) => i["4-PressureA"]), type: "scatter", mode: "lines" } ].filter(({ name }) => plotOptions[name]); return ( <Plot data={plotData} layout={{ width: 1000, height: 1000, title: "A Fancy Plot" }} /> ); } else { return <h1>No Data Loaded</h1>; } } } export default FiltrationPlots;
over 4 years ago · Santiago Trujillo
14 Respuestas
Responde la pregunta

0

Gracias a Alex Mckay, tuve la determinación de configurar dinámicamente los accesorios:

 for(let prop in filter) (state.filter as Record<string, any>)[prop] = filter[prop];
over 4 years ago · Santiago Trujillo Denunciar

0

Cuando hacemos algo como este obj[key] Typescript no puede saber con certeza si esa clave existe en ese objeto. Lo que hice:

 Object.entries(data).forEach(item => { formData.append(item[0], item[1]); });
over 4 years ago · Santiago Trujillo Denunciar

0

Sin error typescript

 const formData = new FormData(); Object.keys(newCategory).forEach((k,i)=>{ var d =Object.values(newCategory)[i]; formData.append(k,d) })
over 4 years ago · Santiago Trujillo Denunciar

0

He hecho una simulación del problema. parece que el problema es cómo debemos acceder a las propiedades de los objetos dinámicamente usando la notación de corchetes en TypeScript

 interface IUserProps { name: string; age: number; } export default class User { constructor(private data: IUserProps) {} get(propName: string): string | number { return this.data[propName as keyof IUserProps]; } }

Encontré un blog que podría ser útil para entender esto mejor.

aquí hay un enlace https://www.nadershamma.dev/blog/2019/how-to-access-object-properties-dynamically-using-bracket-notation-in-typescript/

over 4 years ago · Santiago Trujillo Denunciar

0

Yo uso esto:

 interface IObjectKeys { [key: string]: string | number; } interface IDevice extends IObjectKeys { id: number; room_id: number; name: string; type: string; description: string; }

NOTA: "[clave: cadena]" ¿qué es? Un objeto en JavaScript es principalmente una colección de propiedades formada por pares clave-valor. Además, la clave solo puede ser una cadena (incluso para elementos de matriz), pero el valor puede ser cualquier tipo de datos.

Si usa la propiedad opcional en su objeto:

 interface IDevice extends IObjectKeys { id: number; room_id?: number; name?: string; type?: string; description?: string; }

... debe agregar el valor 'indefinido' en la interfaz IObjectKeys:

 interface IObjectKeys { [key: string]: string | number | undefined; }
over 4 years ago · Santiago Trujillo Denunciar

0

Hice algunos pequeños cambios en la función/uso de Alex McKay que creo que hacen que sea un poco más fácil seguir por qué funciona y también se adhiere a la regla de no usar antes de definir .

Primero, defina esta función para usar:

 const getKeyValue = function<T extends object, U extends keyof T> (obj: T, key: U) { return obj[key] }

En la forma en que lo he escrito, el genérico de la función enumera el objeto primero, luego la propiedad en el objeto en segundo lugar (estos pueden ocurrir en cualquier orden, pero si especifica U extends key of T antes de que T extends object , rompe el regla no-use-before-define , y también tiene sentido tener el objeto primero y su propiedad en segundo lugar.Finalmente, he usado la sintaxis de función más común en lugar de los operadores de flecha ( => ).

De todos modos, con esas modificaciones puedes usarlo así:

 interface User { name: string; age: number; } const user: User = { name: "John Smith", age: 20 }; getKeyValue(user, "name")

Lo cual, de nuevo, me parece un poco más legible.

over 4 years ago · Santiago Trujillo Denunciar

0

Al usar Object.keys , lo siguiente funciona:

 Object.keys(this) .forEach(key => { console.log(this[key as keyof MyClass]); });
over 4 years ago · Santiago Trujillo Denunciar

0

getUserName público (): cadena {

 const accessToken = this.getAccessToken(); const claims:any = this.getUserClaims(); console.log('access token ',accessToken); this.getUserInfo(); return claims['sub'].split('@')[0];

}

// dar cualquier tipo a la variable

over 4 years ago · Santiago Trujillo Denunciar

0

Sé que es un poco tarde, pero todo lo que se necesita es agregar un poco de conversión de tipos. Escribí una función estática que devuelve de forma segura la matriz de teclas con la escritura correcta. Todo lo que necesita es definir el tipo y pasar el objeto como parámetro:

 export class ObjectUtil { public static getObjectKeys<T>(obj: Object) { if (!obj) { return []; } return Object.keys(obj).map((key: string) => key as keyof T); } }

A continuación se muestra un ejemplo sencillo:

 ObjectUtil.getObjectKeys<Address>(address).forEach((key) => { console.log(address[key]); });
over 4 years ago · Santiago Trujillo Denunciar

0

Esta no es una respuesta a la pregunta original, sino una solución genérica a este problema.

Problema original: person[cr.field] provoca este error


Estoy haciendo un formulario genérico de búsqueda avanzada donde el usuario puede seleccionar un campo, un comparador y el valor deseado. Cuando intento leer el valor del objeto en función de la clave, aparece este error (aunque el valor del field es un tipo de cadena y creo que debería estar bien)

Entonces, lo que hago es extraer la [clave, valor] así

 const x: [string, any] = Object.entries(person).find(([key, _]) => key === cr.field);

Por ejemplo, si mi criterio ( cr ) es { field: 'name', value: 'John' } y el name del campo realmente existe en un objeto de persona, debería devolver el nombre del campo y el valor como tupla (x es [string, any] o undef). Si no se encuentra, indefinido.

over 4 years ago · Santiago Trujillo Denunciar

0

Para cualquiera que se tope con esto en el futuro:

Si recibe el error de TypeScript

'...la expresión de tipo cadena no se puede usar para indexar...'

luego simplemente especifique que la 'expresión de tipo cadena' es una clave del tipo de ese objeto. Por ejemplo,

 const someObj:ObjectType = data; const field = 'username'; // This gives an error const temp = someObj[field]; // Solution 1: When the type of the object is known const temp = someObj[field as keyof ObjectType] // Solution 2: When the type of the object is not known const temp = someObj[field as keyof typeof someObj]
over 4 years ago · Santiago Trujillo Denunciar

0

Esto es lo que funcionó para mí. El tsconfig.json tiene una opción noImplicitAny que se configuró en true , simplemente la configuré en false y ahora puedo acceder a las propiedades de los objetos usando cadenas.

over 4 years ago · Santiago Trujillo Denunciar

0

// bad const _getKeyValue = (key: string) => (obj: object) => obj[key]; // better const _getKeyValue_ = (key: string) => (obj: Record<string, any>) => obj[key]; // best const getKeyValue = <T extends object, U extends keyof T>(key: U) => (obj: T) => obj[key];

Incorrecto: el motivo del error es que el tipo de object es solo un objeto vacío de forma predeterminada. Por lo tanto, no es posible usar un tipo de string para indexar {} .

Mejor: la razón por la que desaparece el error es porque ahora le estamos diciendo al compilador que el argumento obj será una colección de pares cadena/valor ( string/any ). Sin embargo, estamos usando any tipo, por lo que podemos hacerlo mejor.

Óptimo - T extiende el objeto vacío. U extiende las claves de T . Por lo tanto, U siempre existirá en T , por lo tanto, puede usarse como un valor de búsqueda.

Aquí hay un ejemplo completo:

Cambié el orden de los genéricos ( U extends keyof T ahora viene antes de T extends object ) para resaltar que el orden de los genéricos no es importante y debe seleccionar el orden que tenga más sentido para su función.

 const getKeyValue = <U extends keyof T, T extends object>(key: U) => (obj: T) => obj[key]; interface User { name: string; age: number; } const user: User = { name: "John Smith", age: 20 }; const getUserName = getKeyValue<keyof User, User>("name")(user); // => 'John Smith'

Sintaxis alternativa

 const getKeyValue = <T, K extends keyof T>(obj: T, key: K): T[K] => obj[key];
over 4 years ago · Santiago Trujillo Denunciar

0

Esto sucede porque intenta acceder a la propiedad plotOptions usando el name de la cadena. TypeScript entiende que el name puede tener cualquier valor, no solo el nombre de la propiedad de plotOptions . Por lo tanto, TypeScript requiere agregar una firma de índice a plotOptions , para que sepa que puede usar cualquier nombre de propiedad en plotOptions . Pero sugiero cambiar el tipo de name , por lo que solo puede ser una de las propiedades de plotOptions .

 interface trainInfo { name: keyof typeof plotOptions; x: Array<number>; y: Array<number>; type: string; mode: string; }

Ahora podrá usar solo los nombres de propiedades que existen en plotOptions .

También tienes que cambiar ligeramente tu código.

Primero asigne una matriz a alguna variable temporal, para que TS conozca el tipo de matriz:

 const plotDataTemp: Array<trainInfo> = [ { name: "train_1", x: data.filtrationData.map((i: any) => i["1-CumVol"]), y: data.filtrationData.map((i: any) => i["1-PressureA"]), type: "scatter", mode: "lines" }, // ... }

Luego filtrar:

 const plotData = plotDataTemp.filter(({ name }) => plotOptions[name]);

Si está obteniendo datos de la API y no tiene forma de escribir accesorios de verificación en el momento de la compilación, la única forma es agregar la firma de índice a sus plotOptions :

 type tplotOptions = { [key: string]: boolean } const plotOptions: tplotOptions = { train_1: true, train_2: true, train_3: true, train_4: true }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda