Soy bastante nuevo en TypeScript y trato de descubrir cómo manejar mejor este escenario en el que me encuentro.
Cuando tengo una función y paso un objeto escrito a esa función, necesito acceder a las propiedades de ese objeto con una variable como obj[key] . Intentar acceder a una propiedad como esa arroja un error como:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ScrapedBuilding'. No index signature with a parameter of type 'string' was found on type
Tiene sentido, así que puedo agregar algo como [key: string]: string | number que satisface ese error, pero ahora puedo agregar cualquier propiedad a mi objeto haciendo que el punto de escribir el objeto en primer lugar no tenga sentido.
¿Cómo puedo acceder a las propiedades de mi objeto con una variable, pero aún tengo un objeto fuertemente tipado?
un pequeño ejemplo
function foo(data: DataDef) { const key = some logic to determine what property const prop = data[key] // Error unless I allow [key: type]: type }Aquí hay un ejemplo de lo que estás tratando de hacer, creo. En su ejemplo, tenía "algo de lógica para determinar qué propiedad", así que pensé que necesitaba recorrer el objeto allí. En este caso, verifiqué si la clave era igual a la cadena "primero", podría hacer cualquier lógica allí y aún así usar la clave para obtener la propiedad de los datos.
type Data = { first: number; second: number; third: number; }; const data = { first: 1, second: 2, third: 3 }; const getFirst = (data: Data): number => { for (const [key, value] of Object.entries(data)) { console.log(`${key}: ${value}`); if (key === "first") { return data[key]; } } return -1; };Otra buena manera de hacer lo que está intentando es usar una enumeración para indexar el objeto, ya que la enumeración está definida y no cualquier cadena aleatoria, no se encontrará con el mismo problema. Prefiero usar enumeraciones para tener objetos fuertemente tipados.
enum DataEnum { first = "first", second = "second", third = "third" } interface DataTypeEnum { [DataEnum.first]: number; [DataEnum.second]: number; [DataEnum.third]: number; } const dataEnum = { [DataEnum.first]: 1, [DataEnum.second]: 2, [DataEnum.third]: 3, } const getFirstEnum = (d: DataTypeEnum): number => { for (const [key, value] of Object.entries(d)) { console.log(`${key}: ${value}`); if (key === DataEnum.first) { return d[key]; } } return -1; };Dos caminos.
type Data = { first: number; second: number; third: number; }; type DataProps = Data;o, si las propiedades no son necesarias,
type DataProps = 'first'|'second'|'third'; type Data = Record<DataProps, number>;De todas formas,
const data: Data = { first: 1, second: 2, third: 3 }; function getProp(data: Data, key: DataProps) { return data[key]; }Deberia trabajar.