Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

1.4K
Views
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 answers
Answer question

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!