settitle route page navigationend example change based typescript reflection metaprogramming

typescript - route - Manera segura de extraer nombres de propiedades



navigationend example (3)

Estoy buscando una forma de obtener un nombre de propiedad de objeto con una comprobación de tipo que permita detectar posibles regresiones después de la refactorización.

Aquí hay un ejemplo: el componente donde tengo que pasar los nombres de propiedad como cadenas y se romperá si intentaré cambiar los nombres de propiedad en el modelo.

interface User { name: string; email: string; } class View extends React.Component<any, User> { constructor() { super(); this.state = { name: "name", email: "email" }; } private onChange = (e: React.FormEvent) => { let target = e.target as HTMLInputElement; this.state[target.id] = target.value; this.setState(this.state); } public render() { return ( <form> <input id={"name"} value={this.state.name} onChange={this.onChange}/> <input id={"email"} value={this.state.email} onChange={this.onChange}/> <input type="submit" value="Send" /> </form> ); } }

Apreciaría si hay alguna buena solución para resolver este problema.


En TS 2.1 se introdujo la palabra clave keyof que hizo esto posible:

const propertyOf = <TObj>(name: keyof TObj) => name;

o

const propertyNamesOf = <TObj>(obj: TObj = null) => (name: keyof TObj) => name;

Estos se pueden usar así:

propertyOf<MyObj>("myProperty");

o

const myObjProperties = propertyNamesOf<MyObj>(); myObjProperties("myProperty");

o

const myObjProperties = propertyNamesOf(myObj); myObjProperties("myProperty");

Esto dará un error si myProperty no es una propiedad del tipo MyObj.

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html


En este momento no hay realmente una buena forma de hacer esto, pero actualmente hay algunas sugerencias abiertas en github (ver #1579 , #394 y #1003 ).

Lo que puede hacer es lo que se muestra en esta respuesta: envuelva la referencia de la propiedad en una función, convierta la función en una cadena y luego extraiga el nombre de la propiedad de la cadena.

Aquí hay una función para hacer eso:

function getPropertyName(propertyFunction: Function) { return //.([^/.;]+);?/s*/}$/.exec(propertyFunction.toString())[1]; }

Entonces utilízalo así:

// nameProperty will hold "name" const nameProperty = getPropertyName(() => this.state.name);

Esto podría no funcionar dependiendo de cómo se minimice el código, así que ten cuidado.

Actualizar

Es más seguro hacer esto en tiempo de compilación. Escribí ts-nameof así que esto es posible:

nameof<User>(s => s.name);

Compila a:

"name";


Esto es específicamente para los desarrolladores React / React-Native.

Para obtener de forma segura el nombre de la propiedad, uso la siguiente clase:

export class BaseComponent<P = {}, S = {}> extends Component<P, S> { protected getPropName = (name: keyof P) => name; protected getStateName = (name: keyof S) => name; }

Y reemplazado extends React.Component<PropTypes> con extends BaseComponnent<PropTypes ,

Ahora, con el Component que puede llamar, this.getPropName(''yourPropName'') para obtener el nombre de la propiedad.