Tengo muchas tablas en Lovefield y sus respectivas interfaces para las columnas que tienen.
Ejemplo:
export interface IMyTable {
id: number;
title: string;
createdAt: Date;
isDeleted: boolean;
}
Me gustaría tener los nombres de propiedad de esta interfaz en una matriz como esta:
const IMyTable = ["id", "title", "createdAt", "isDeleted"];
no puedo crear un objeto / matriz basado en la interfaz IMyTable
directamente, lo que debería funcionar porque obtendría los nombres de la interfaz de las tablas de forma dinámica. Por lo tanto, necesito iterar sobre estas propiedades en la interfaz y obtener una matriz.
¿Cómo consigo este resultado?
fuente
ts_transformer_keys_1.keys is not a function
cuando sigo los pasos exactos en la documentación. ¿Hay alguna solución a esto?ts_transformer_keys_1.keys is not a function
Lo siguiente requiere que enumere las claves por su cuenta, pero al menos TypeScript se aplicará
IUserProfile
yIUserProfileKeys
tendrá exactamente las mismas claves (Required<T>
se agregó en TypeScript 2.8 ):fuente
IUserProfile
y sería fácil extraerlas de constIUserProfileKeys
. Esto es exactamente lo que estaba buscando. No es necesario convertir todas mis interfaces en clases ahora.Tuve un problema similar: tenía una lista gigante de propiedades para las que quería tener una interfaz y un objeto fuera de ella.
NOTA: ¡No quería escribir (escribir con el teclado) las propiedades dos veces! Solo SECO.
Una cosa a tener en cuenta aquí es que las interfaces son tipos obligatorios en tiempo de compilación, mientras que los objetos son principalmente en tiempo de ejecución. ( Fuente )
Como @derek mencionó en otra respuesta , el denominador común de interfaz y objeto puede ser una clase que sirve tanto para un tipo como para un valor .
Entonces, TL; DR, el siguiente fragmento de código debería satisfacer las necesidades:
( Aquí está el código anterior en Typecript Playground para jugar más)
PD. Si no desea asignar valores iniciales a las propiedades en la clase y permanecer con el tipo, puede hacer el truco del constructor:
Truco de constructor en TypeScript Playground .
fuente
propsArray
embargo, solo se puede acceder a él cuando inicializó las claves.propsArray
está disponible antes detableInstance
si eso es lo que quiere decir, tan claramente antes de la inicialización de la instancia. Sin embargo, si se refiere a los valores falsos asignados enMyTableClass
, estos están ahí para implicar brevemente el "tipo" de las propiedades. Si no los quiere, puede seguir el truco del constructor en el ejemplo de PS.MyTableClass
con el último y esperar recibir claves en elpropsArray
ya que las vars y tipos no inicializados se eliminan en tiempo de ejecución. Siempre debe proporcionarles algún tipo de valor predeterminado. Descubrí que inicializarlos conundefined
es el mejor enfoque.readonly
y?
en los parámetros. Acabo de actualizar eso. Gracias por señalar. Ahora creo que funciona de la manera que dijo, es engañoso y no puede funcionar. :)Esto debería funcionar
o
fuente
var IMyTable: Array<keyof IMyTable> = ["id", "createdAt", "id"];
Tal vez sea demasiado tarde, pero en la versión 2.1 de mecanografiado puede usar
key of
así:Documento: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types
fuente
En lugar de definir
IMyTable
como en interfaz, intente definirlo como una clase. En mecanografiado puedes usar una clase como una interfaz.Entonces, para su ejemplo, defina / genere su clase de esta manera:
Úselo como interfaz:
Obtener claves:
fuente
Necesitará crear una clase que implemente su interfaz, instanciarla y luego usarla
Object.keys(yourObject)
para obtener las propiedades.luego
fuente
Cannot extend an interface […]. Did you mean 'implements'?
Sin embargo, usar en suimplements
lugar requiere copiar manualmente la interfaz, que es exactamente lo que no quiero.implements
y he actualizado mi respuesta. Como ha dicho @basarat, las interfaces no existen en tiempo de ejecución, por lo que la única forma es implementarlas como una clase.@types/react
). Los copié manualmente, pero eso no es a prueba de futuro 😪 Estoy tratando de vincular dinámicamente métodos que no son del ciclo de vida (que ya están vinculados), pero no están declarados en React.Component (la clase).No existe una forma sencilla de crear una matriz de claves desde una interfaz. Los tipos se borran en tiempo de ejecución y los tipos de objetos (sin ordenar, con nombre) no se pueden convertir a tipos de tupla (ordenados, sin nombre) sin algún tipo de truco.
Opción 1: Aproximación manual
(+) tipo de retorno de matriz simple (-), sin tupla (+ -) escritura manual con autocompletado
Extensión: Podríamos intentar ser elegantes y usar tipos recursivos para generar una tupla. Esto solo funcionó para mí para un par de accesorios (~ 5,6) hasta que el rendimiento se degradó enormemente. El tipo recursivo profundamente anidado tampoco es compatible oficialmente con TS: enumero este ejemplo aquí para completarlo.
Opción 2: generador de código basado en la API del compilador de TS ( ts-morph )
Después de compilar y ejecutar este archivo con
tsc && node dist/mybuildstep.js
,./src/generated/IMyTable-keys.ts
se genera un archivo con el siguiente contenido:(+) solución automática (+) tipo de tupla exacta (-) requiere paso de compilación
PD: He elegido
ts-morph
, ya que es una alternativa simple a la API del compilador TS original.fuente
Hipocresía. Las interfaces no existen en tiempo de ejecución.
solución alterna
Crea una variable del tipo y
Object.keys
úsala 🌹fuente
var abc: IMyTable = {}; Object.keys(abc).forEach((key) => {console.log(key)});
var abc: IMyTable = {}
porque el literal de objeto vacío no se ajusta a la forma de esa interfaz.No puedes hacerlo. Las interfaces no existen en tiempo de ejecución (como dijo @basarat ).
Ahora, estoy trabajando con lo siguiente:
fuente
fuente
console.log(Tes.id)
por supuesto, el error 'Error de referencia no detectado: Tes no está definido'