Existe uma maneira de analisar strings como JSON em Typescript.
Exemplo: Em JS, podemos usar JSON.parse()
. Existe uma função semelhante em Typescript?
Eu tenho uma string de objeto JSON da seguinte maneira:
{"name": "Bob", "error": false}
javascript
json
string
typescript
ssd20072
fonte
fonte
JSON.parse
obtém um objeto como resultado e não umstring
(veja minha resposta para mais informações). Se você quiser transformar um objeto em uma string, você precisa usarJSON.stringify
.Respostas:
Texto tipográfico é (um superconjunto de) javascript, então você apenas usa
JSON.parse
como faria em javascript:Apenas que no texto digitado você pode ter um tipo para o objeto resultante:
( código no playground )
fonte
'{ "myString": "string", "myNumber": 4 }'
por'{ "myString": "string", "myNumberBAD": 4 }'
não falhará e obj.myNumber retornará indefinido.Json.parse(text).validate[MyObj]
. playframework.com/documentation/2.6.x/ScalaJson como você pode fazer o mesmo no texto datilografado (talvez haja uma biblioteca externa para fazer isso?)?MyObj
não existe. Existem muitos outros tópicos no SO sobre este assunto, por exemplo: Verifique se um objeto implementa uma interface em tempo de execução com TypeScriptTipo seguro
JSON.parse
Você pode continuar a usar
JSON.parse
, já que TS é um superconjunto JS. Resta um problema:JSON.parse
devoluçõesany
, o que prejudica a segurança de tipo. Aqui estão duas opções para tipos mais fortes:1. Protetores de tipo definido pelo usuário ( playground )
Protetores de tipo personalizado são a solução mais simples e muitas vezes suficientes para validação de dados externos:
UMA
Exemplo de uso:JSON.parse
wrapper pode então pegar um protetor de tipo como entrada e retornar o valor digitado analisado:safeJsonParse
pode ser estendido para falhar rapidamente ouJSON.parse
erros de tentativa / captura .2. Bibliotecas externas
Escrever funções de proteção de tipo manualmente torna-se complicado, se você precisar validar muitos valores diferentes. Existem bibliotecas para auxiliar nesta tarefa - exemplos (nenhuma lista abrangente):
io-ts
: rel. popular (3,2 mil estrelas atualmente),fp-ts
dependência de pares, estilo de programação funcionalzod
: bastante novo (repo: 2020-03-07), se esforça para ser mais procedimental / orientado a objetos do queio-ts
typescript-is
: Transformador TS para API do compilador, wrapper adicional como ttypescript necessáriotypescript-json-schema
/ajv
: Criar esquema JSON a partir de tipos e validá-lo comajv
Mais informações
fonte
Se você deseja que seu JSON tenha um tipo Typecript validado, você mesmo precisará fazer esse trabalho de validação. Isso não é novidade. Em Javascript simples, você precisa fazer o mesmo.
Validação
Gosto de expressar minha lógica de validação como um conjunto de "transformações". Eu defino a
Descriptor
como um mapa de transformações:Então, posso criar uma função que aplicará essas transformações a uma entrada arbitrária:
Agora, não estou apenas validando minha entrada JSON, mas estou construindo um tipo de escrita à medida que prossigo. Os tipos genéricos acima garantem que o resultado infere os tipos de suas "transformações".
No caso de a transformação gerar um erro (que é como você implementaria a validação), gostaria de envolvê-la com outro erro mostrando qual chave causou o erro.
Uso
Em seu exemplo, eu usaria isso da seguinte maneira:
Agora
value
serão digitados, visto queString
eBoolean
são ambos "transformadores" no sentido de que recebem a entrada e retornam uma saída digitada.Além disso, o
value
será realmente desse tipo. Em outras palavras, sename
fosse realmente123
, ele será transformado para"123"
para que você tenha uma string válida. Isso ocorre porque usamosString
em tempo de execução, uma função integrada que aceita entrada arbitrária e retorna umstring
.Você pode ver isso funcionando aqui . Tente o seguinte para se convencer:
const value
definição para ver se o pop-over mostra o tipo correto."Bob"
para123
e execute novamente a amostra. No console, você verá que o nome foi convertido corretamente para a string"123"
.fonte
name
fosse realmente123
, ele será transformado para"123"
. Isso parece estar incorreto. Meu nãovalue
voltará quando eu copiar e colar todo o seu código exatamente e fizer essa alteração.{name: 123..
{name:"123"..
123
vez de"Bob"
).Transformed
tipo. Você pode apenas usarObject
.type Descriptor<T extends Object> = { ... };
Transformed
tipo é totalmente desnecessário. Eu atualizei a resposta de acordo.Além disso, você pode usar bibliotecas que realizam validação de tipo de seu json, como Sparkson . Eles permitem que você defina uma classe TypeScript, para a qual você gostaria de analisar sua resposta, no seu caso poderia ser:
A biblioteca irá validar se os campos obrigatórios estão presentes na carga JSON e se seus tipos estão corretos. Ele também pode fazer várias validações e conversões.
fonte
Há uma ótima biblioteca para isso ts-json-object
No seu caso, você precisaria executar o seguinte código:
Esta biblioteca irá validar o json antes de analisar
fonte
JSON.parse
está disponível em TypeScript, então você pode apenas usá-lo:No entanto, você frequentemente desejará analisar um objeto JSON enquanto verifica se ele corresponde a um determinado tipo, em vez de lidar com um valor do tipo
any
. Nesse caso, você pode definir uma função como a seguinte:Essa função pega uma string JSON e um objeto contendo funções individuais que carregam cada campo do objeto que você está criando. Você pode usá-lo assim:
fonte