Eu tenho muitas tabelas no Lovefield e suas respectivas interfaces para as colunas que eles têm.
Exemplo:
export interface IMyTable {
id: number;
title: string;
createdAt: Date;
isDeleted: boolean;
}
Eu gostaria de ter os nomes das propriedades desta interface em uma matriz como esta:
const IMyTable = ["id", "title", "createdAt", "isDeleted"];
Não posso fazer um objeto / matriz com base na interface IMyTable
diretamente, o que deve funcionar porque estaria obtendo os nomes das interfaces das tabelas dinamicamente. Portanto, preciso iterar sobre essas propriedades na interface e obter uma matriz dela.
Como faço para alcançar esse resultado?
fonte
ts_transformer_keys_1.keys is not a function
quando sigo as etapas exatas na documentação. existe uma solução alternativa para isso?ts_transformer_keys_1.keys is not a function
O seguinte requer que você liste as chaves por conta própria, mas pelo menos o TypeScript aplicará
IUserProfile
eIUserProfileKeys
terá exatamente as mesmas chaves (Required<T>
foi adicionado no TypeScript 2.8 ):fonte
IUserProfile
e seria fácil extraí-las de constIUserProfileKeys
. Isso é exatamente o que estou procurando. Não há necessidade de converter todas as minhas interfaces em classes agora.Tive um problema semelhante, pois tinha uma lista gigante de propriedades das quais queria ter uma interface e um objeto fora dela.
NOTA: Eu não queria escrever (digitar com o teclado) as propriedades duas vezes! Apenas SECO.
Uma coisa a ser observada aqui é que as interfaces são tipos impostos em tempo de compilação, enquanto os objetos são em sua maioria em tempo de execução. ( Fonte )
Como @derek mencionou em outra resposta , o denominador comum de interface e objeto pode ser uma classe que serve tanto um tipo quanto um valor .
Portanto, TL; DR, o seguinte trecho de código deve satisfazer as necessidades:
( Aqui está o código acima no Playground Typescript para jogar mais)
PS. Se você não quiser atribuir valores iniciais às propriedades da classe e ficar com o tipo, pode fazer o truque do construtor:
Truque do construtor no Playground TypeScript .
fonte
propsArray
só está acessível quando você inicializou as chaves.propsArray
está disponível antes detableInstance
se é isso que você quer dizer, então claramente antes da inicialização da instância. No entanto, se você está se referindo aos valores falsos atribuídos emMyTableClass
, eles estão ali apenas para sugerir o "tipo" das propriedades. Se não os quiser, pode usar o truque do construtor no exemplo PS.MyTableClass
com o último e esperar receber as chaves napropsArray
medida que vars e tipos não inicializados são removidos no tempo de execução. Você sempre deve fornecer a eles algum tipo de valor padrão. Descobri que inicializá-los comundefined
é a melhor abordagem.readonly
e?
nos parâmetros. Acabei de atualizar isso. Obrigado por apontar. Agora acho que funciona da maneira que você disse, é enganoso e não pode funcionar. :)Isso deve funcionar
ou
fonte
var IMyTable: Array<keyof IMyTable> = ["id", "createdAt", "id"];
Talvez seja tarde demais, mas na versão 2.1 do texto datilografado você pode usar
key of
assim:Doc: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types
fonte
Em vez de definir
IMyTable
como uma interface, tente defini-la como uma classe. No texto datilografado, você pode usar uma classe como uma interface.Então, para seu exemplo, defina / gere sua classe assim:
Use-o como uma interface:
Obtenha as chaves:
fonte
Você precisará fazer uma classe que implemente sua interface, instanciá-la e usar
Object.keys(yourObject)
para obter as propriedades.então
fonte
Cannot extend an interface […]. Did you mean 'implements'?
No entanto, usar emimplements
vez disso requer a cópia manual da interface, que é exatamente o que eu não quero.implements
e eu atualizei minha resposta. Como @basarat afirmou, as interfaces não existem em tempo de execução, então a única maneira é implementá-las como uma classe.@types/react
). Eu os copiei manualmente, mas isso dificilmente é à prova de futuro 😪 Estou tentando vincular dinamicamente métodos que não são do ciclo de vida (que já estão vinculados), mas eles não são declarados em React.Component (a classe).Não posso. As interfaces não existem em tempo de execução.
Gambiarra
Crie uma variável do tipo e use
Object.keys
nela 🌹fonte
var abc: IMyTable = {}; Object.keys(abc).forEach((key) => {console.log(key)});
var abc: IMyTable = {}
porque o literal do objeto vazio não está de acordo com a forma dessa interface.Não existe uma maneira fácil de criar um array de chaves a partir de uma interface. Os tipos são apagados em tempo de execução e os tipos de objetos (não ordenados, nomeados) não podem ser convertidos em tipos de tupla (ordenados, não nomeados) sem algum tipo de hack.
Opção 1: abordagem manual
(+) tipo de retorno de array simples (-), sem tupla (+ -) escrita manual com preenchimento automático
Extensão: podemos tentar ser extravagantes e usar tipos recursivos para gerar uma tupla. Isso só funcionou para mim por alguns adereços (~ 5,6) até o desempenho degradar enormemente. Tipos recursivos profundamente aninhados também não são oficialmente suportados pelo TS - listo este exemplo aqui para fins de completude.
Opção 2: gerador de código baseado na API do compilador TS ( ts-morph )
Depois de compilar e executar esse arquivo com
tsc && node dist/mybuildstep.js
, um arquivo./src/generated/IMyTable-keys.ts
com o seguinte conteúdo é gerado:(+) solução automática (+) tipo de tupla exata (-) requer etapa de construção
PS: Eu escolhi
ts-morph
, pois é uma alternativa simples para a API do compilador TS original.fonte
Você não pode fazer isso. As interfaces não existem em tempo de execução (como @basarat disse).
Agora, estou trabalhando com o seguinte:
fonte
fonte
console.log(Tes.id)
que, claro, seria o erro 'Erro de referência não capturado: Tes não está definido'