Typescript에서 문자열을 JSON으로 구문 분석하는 방법이 있습니까?
예 : JS에서는 JSON.parse()
. Typescript에 비슷한 기능이 있습니까?
다음과 같이 JSON 개체 문자열이 있습니다.
{"name": "Bob", "error": false}
답변
Typescript는 자바 스크립트의 상위 집합이므로 자바 스크립트에서 JSON.parse
와 같이 사용하면 됩니다.
let obj = JSON.parse(jsonString);
typescript에서만 결과 객체에 유형을 가질 수 있습니다.
interface MyObj {
myString: string;
myNumber: number;
}
let obj: MyObj = JSON.parse('{ "myString": "string", "myNumber": 4 }');
console.log(obj.myString);
console.log(obj.myNumber);
( 놀이터의 코드 )
답변
형식 안전 JSON.parse
JSON.parse
TS는 JS 수퍼 세트이므로을 계속 사용할 수 있습니다 . 여전히 문제가 남아 있습니다. JSON.parse
returns any
, 이는 유형 안전성을 약화시킵니다. 더 강력한 유형에 대한 두 가지 옵션은 다음과 같습니다.
1. 사용자 정의 유형 가드 ( 놀이터 )
사용자 지정 유형 가드 는 가장 간단한 솔루션이며 종종 외부 데이터 유효성 검사에 충분합니다.
// For example, you expect to parse a given value with `MyType` shape
type MyType = { name: string; description: string; }
// Validate this value with a custom type guard
function isMyType(o: any): o is MyType {
return "name" in o && "description" in o
}
JSON.parse
래퍼는 입력으로 형 가드를 타고 구문 분석, 입력 값을 반환 할 수 있습니다 :
const safeJsonParse = <T>(guard: (o: any) => o is T) => (text: string): ParseResult<T> => {
const parsed = JSON.parse(text)
return guard(parsed) ? { parsed, hasError: false } : { hasError: true }
}
type ParseResult<T> =
| { parsed: T; hasError: false; error?: undefined }
| { parsed?: undefined; hasError: true; error?: unknown }
사용 예 :
const json = '{ "name": "Foo", "description": "Bar" }';
const result = safeJsonParse(isMyType)(json) // result: ParseResult<MyType>
if (result.hasError) {
console.log("error :/") // further error handling here
} else {
console.log(result.parsed.description) // result.parsed now has type `MyType`
}
safeJsonParse
빠른 실패 또는 try / catch JSON.parse
오류 로 확장 될 수 있습니다 .
2. 외부 라이브러리
다양한 값의 유효성을 검사해야하는 경우 유형 보호 함수를 수동으로 작성하는 것이 번거 롭습니다. 이 작업을 지원하는 라이브러리가 있습니다-예 (전체 목록 없음) :
io-ts
: rel. 인기 (현재 32,000 개 별),fp-ts
피어 종속성, 함수형 프로그래밍 스타일zod
: 아주 새로운 (REPO : 2020년 3월 7일)는 최선의 노력을 기울이고 있습니다 더있을 수 있습니다 절차 / 객체 지향 보다io-ts
typescript-is
: 컴파일러 API 용 TS 변환기, ttypescript 와 같은 추가 래퍼 필요typescript-json-schema
/ajv
: 유형에서 JSON 스키마를 생성하고ajv
더 많은 정보
답변
JSON에 유효성이 검사 된 Typescript 유형이 포함되도록하려면 유효성 검사 작업을 직접 수행해야합니다. 이것은 새로운 것이 아닙니다. 일반 Javascript에서는 동일한 작업을 수행해야합니다.
확인
내 유효성 검사 논리를 “변환”집합으로 표현하고 싶습니다. Descriptor
변환 맵으로 정의합니다 .
type Descriptor<T> = {
[P in keyof T]: (v: any) => T[P];
};
그런 다음 이러한 변환을 임의의 입력에 적용하는 함수를 만들 수 있습니다.
function pick<T>(v: any, d: Descriptor<T>): T {
const ret: any = {};
for (let key in d) {
try {
const val = d[key](v[key]);
if (typeof val !== "undefined") {
ret[key] = val;
}
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
throw new Error(`could not pick ${key}: ${msg}`);
}
}
return ret;
}
이제 JSON 입력의 유효성을 검사 할뿐만 아니라 Typescript 유형을 구축하고 있습니다. 위의 일반 유형은 결과가 “변환”에서 유형을 유추하도록합니다.
변환에서 오류가 발생하는 경우 (유효성 검사를 구현하는 방법) 오류를 일으킨 키를 보여주는 다른 오류로 래핑하고 싶습니다.
용법
귀하의 예에서는 다음과 같이 사용합니다.
const value = pick(JSON.parse('{"name": "Bob", "error": false}'), {
name: String,
error: Boolean,
});
이제 value
부터, 입력됩니다 String
및 Boolean
그들이 입력을하고 형식화 된 출력을 반환 의미에서 모두 “트랜스 포머”입니다.
또한, value
의지가 실제로 할 유형. 즉, name
실제로 123
이면 "123"
유효한 문자열을 갖도록 로 변환됩니다 . 이는 String
임의의 입력을 받아들이고를 반환하는 내장 함수 인 런타임에 사용했기 때문 string
입니다.
여기서 작동하는 것을 볼 수 있습니다 . 자신을 설득하기 위해 다음을 시도하십시오.
const value
정의 위로 마우스를 가져 가서 팝업에 올바른 유형이 표시되는지 확인합니다.- 변화 시도
"Bob"
에123
샘플을 다시 실행합니다. 콘솔에서 이름이 문자열로 올바르게 변환되었음을 확인할 수"123"
있습니다.
답변
Sparkson 과 같이 json의 유형 유효성 검사를 수행하는 라이브러리를 추가로 사용할 수 있습니다 . 응답을 구문 분석하려는 TypeScript 클래스를 정의 할 수 있습니다.
import { Field } from "sparkson";
class Response {
constructor(
@Field("name") public name: string,
@Field("error") public error: boolean
) {}
}
라이브러리는 필수 필드가 JSON 페이로드에 있고 해당 유형이 올바른지 확인합니다. 또한 많은 유효성 검사 및 변환을 수행 할 수 있습니다.
답변
이를위한 훌륭한 라이브러리가 있습니다. ts-json-object
귀하의 경우 다음 코드를 실행해야합니다.
import {JSONObject, required} from 'ts-json-object'
class Response extends JSONObject {
@required
name: string;
@required
error: boolean;
}
let resp = new Response({"name": "Bob", "error": false});
이 라이브러리는 파싱하기 전에 json의 유효성을 검사합니다.
답변
JSON.parse
TypeScript에서 사용할 수 있으므로 사용할 수 있습니다.
JSON.parse('{"name": "Bob", "error": false}') // Returns a value of type 'any'
그러나 type 값을 처리하는 대신 특정 유형과 일치하는지 확인하면서 JSON 객체를 구문 분석하는 경우가 많습니다 any
. 이 경우 다음과 같은 함수를 정의 할 수 있습니다.
function parse_json<TargetType extends Object>(
json: string,
type_definitions: { [Key in keyof TargetType]: (raw_value: any) => TargetType[Key] }
): TargetType {
const raw = JSON.parse(json);
const result: any = {};
for (const key in type_definitions) result[key] = type_definitions[key](raw[key]);
return result;
}
이 함수는 생성중인 개체의 각 필드를로드하는 개별 함수가 포함 된 개체와 JSON 문자열을 사용합니다. 다음과 같이 사용할 수 있습니다.
const value = parse_json(
'{"name": "Bob", "error": false}',
{ name: String, error: Boolean, }
);