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

247
Views
¿Conversión similar a un reflejo de la clave a una cadena en TypeScript?

Uso un objeto Proxy con la idea de que cada vez que se actualiza una propiedad, también se puede iniciar algún otro efecto secundario. No quiero iniciar los efectos secundarios en los muchos lugares donde se establecen las propiedades ( principio SECO ).

Código de ejemplo algo artificial:

 const session = new Proxy( { id: undefined as number, age: undefined as number}, // =target { set: (target, property, value): boolean => { switch (property) { case 'id': { target[property] = value; this.notifyIdWasUpdated(value); return true; } case 'age': { target[property] = value; this.updateAgeDisplay(value); return true; } default: { return false; } } } } );

Mi problema es que cuando uso la refactorización de mi IDE para cambiar un nombre de propiedad (clave) del objeto de target (por ejemplo, age ), las constantes de cadena en las declaraciones de case (por ejemplo 'age' ) no se actualizan también (lo que podría causar un insecto).

Pregunta: ¿Hay alguna manera de obtener dinámicamente un valor de cadena 'key' de una expresión obj.key en la declaración del case (que luego sería una prueba de refactorización)? ( Algo así como el inverso del ['key'] , en cierto modo...) Alternativamente, ¿puede sugerir otra forma de estructurar el código anterior para protegerse contra este tipo de supervisión del programador?


  • Encontré Get object property name como una cadena , pero me pregunto si hay una solución menos "dudosa": en mi humilde opinión, la compensación entre un problema potencial y agregar una gran cantidad de código para protegerse no vale la pena. (Muchas técnicas parecen iterar a través de todas las claves y hacer coincidir el tipo de propiedad o el valor; esto no será lo suficientemente seguro).
  • La documentación de Typescript parece decir que la emisión de metadatos para uso similar a la reflexión aún no se ha adoptado oficialmente. En mi humilde opinión, tampoco vale la pena agregar una biblioteca experimental completa solo para esto.
about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Puedes intentar usar keyof aquí.

 interface Session { id: number age: number } const session1 = new Proxy( { id: 0, age: 0 } as Session, { set: (target, property: keyof Session, value): boolean => { switch (property) { case 'id': { target[property] = value; this.notifyIdWasUpdated(value); return true; } case 'age': { target[property] = value; this.updateAgeDisplay(value); return true; } default: { return false; } } } } );

Esto no se renombrará automáticamente, pero TypeScript mostrará un error si la propiedad en case de que no exista en Session .

El siguiente caso debería permitir el cambio de nombre automático:

 interface Session { id: number age: number } type Handlers<Model> = { [Key in keyof Model]: (newValue: Model[Key]) => void; } // Partial<Handlers<Session>> in case you don't want to handle each property const handlers: Handlers<Session> = { id: () => { }, age: () => { }, } const session = new Proxy( { id: 0, age: 0 } as Session, { set: (target, property: keyof Session, value): boolean => { const handler = handlers[property]; if (handler) { handler(value) return true; } return false; } } );
about 4 years ago · Juan Pablo Isaza Report

0

Aunque se eligió otra respuesta , el problema con el código de ejemplo dado se encuentra en un nivel de abstracción algo más alto. Dado que el objeto de session encapsula una serie de propiedades, el objeto de session debe manejarse como una unidad y no las propiedades por separado. (Probablemente haya un nombre de olor en código o alguna otra advertencia contra esto...)

La muestra entonces sería simplemente:

 session = new Proxy( { id: undefined, age: undefined}, // =target { set: (target, property, value): boolean => { if (typeof property === 'string' && Object.keys(target).includes(<string>property)) { target[property] = value; doSideEffects(target); return true; } else { return false; } }, } );

Esto simplifica el controlador en el Proxy.

(Soy el OP. En mi caso, ahora también ha simplificado considerablemente el código de efectos secundarios. Supongo que el efecto del patito de goma entró en juego...)

about 4 years ago · Juan Pablo Isaza Report

0

La solución simple sería algo como esto:

 function nameof<TType>(selector: (t?: TType) => any) { const match = selector .toString() .match(/=>\s*(?:[a-zA-Z0-9_$]+\.?)*?([a-zA-Z0-9_$]+)$/); if (match) { return match[1]; } return undefined; } interface MyType { id: any; age: number; } const session = new Proxy( { id: undefined as number, age: undefined as number }, // =target { set: (target, property, value): boolean => { switch (property) { case nameof<MyType>((t) => t.id): { target[property] = value; this.notifyIdWasUpdated(value); return true; } case nameof<MyType>((t) => t.age): { target[property] = value; this.updateAgeDisplay(value); return true; } default: { return false; } } }, } );

MANIFESTACIÓN

NOTA: ¡Cuidado, si apuntas a ES5! La función de flecha se convierte en una función regular con return para que la expresión regular no funcione, debe cambiar la expresión regular.

about 4 years ago · Juan Pablo Isaza 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!