টাইপসক্রিপ্টে JSON হিসাবে স্ট্রিংকে বিশ্লেষণ করার কোনও উপায় আছে কি?
উদাহরণ: জেএসে, আমরা ব্যবহার করতে পারি JSON.parse()
। টাইপস্ক্রিপ্টে কি একই রকম ফাংশন রয়েছে?
আমার নীচে JSON অবজেক্ট স্ট্রিং রয়েছে:
{"name": "Bob", "error": false}
টাইপসক্রিপ্টে JSON হিসাবে স্ট্রিংকে বিশ্লেষণ করার কোনও উপায় আছে কি?
উদাহরণ: জেএসে, আমরা ব্যবহার করতে পারি JSON.parse()
। টাইপস্ক্রিপ্টে কি একই রকম ফাংশন রয়েছে?
আমার নীচে JSON অবজেক্ট স্ট্রিং রয়েছে:
{"name": "Bob", "error": false}
JSON.parse
আপনি ফলাফল হিসাবে একটি বস্তু পাবেন এবং একটি নয় string
(আরও উত্তর দেওয়ার জন্য আমার উত্তর দেখুন)। আপনি যদি কোনও বস্তুকে স্ট্রিংয়ে রূপান্তর করতে চান তবে তার JSON.stringify
পরিবর্তে আপনার প্রয়োজন ।
উত্তর:
প্রকারভেদটি জাভাস্ক্রিপ্ট (একটি সুপারসেট), তাই আপনি জাভাস্ক্রিপ্টে JSON.parse
যেমন ব্যবহার করেছেন তেমন ব্যবহার করুন :
let obj = JSON.parse(jsonString);
কেবলমাত্র টাইপস্ক্রিপ্টে ফলস্বরূপ অবজেক্টে আপনার টাইপ থাকতে পারে:
interface MyObj {
myString: string;
myNumber: number;
}
let obj: MyObj = JSON.parse('{ "myString": "string", "myNumber": 4 }');
console.log(obj.myString);
console.log(obj.myNumber);
( খেলার মাঠে কোড )
'{ "myString": "string", "myNumber": 4 }'
দ্বারা ইনপুট প্রতিস্থাপন '{ "myString": "string", "myNumberBAD": 4 }'
ব্যর্থ হবে না, এবং obj.myNumber অপরিবর্তিত ফিরে আসবে।
Json.parse(text).validate[MyObj]
। playframework.com/docamentation/2.6.x/ScalaJson আপনি টাইপস্ক্রিপ্টে কীভাবে এটি করতে পারেন (সম্ভবত এটি করার জন্য কোনও বাহ্যিক গ্রন্থাগার রয়েছে?)?
MyObj
উপস্থিত নেই। এই বিষয়টি সম্পর্কে এসও তে প্রচুর অন্যান্য থ্রেড রয়েছে, উদাহরণস্বরূপ: কোনও বস্তু টাইপস্ক্রিপ্ট সহ রানটাইমের সময় একটি ইন্টারফেস প্রয়োগ করে কিনা তা পরীক্ষা করুন
JSON.parse
JSON.parse
টিএস হ'ল জেএস সুপারসেট হিসাবে আপনি ব্যবহার চালিয়ে যেতে পারেন । এখনও একটি সমস্যা বাকি আছে: JSON.parse
রিটার্ন any
, যা প্রকারের সুরক্ষাকে হ্রাস করে। শক্তিশালী প্রকারের জন্য এখানে দুটি বিকল্প রয়েছে:
কাস্টম ধরণের রক্ষীরা হ'ল সহজ সমাধান এবং প্রায়শই বাহ্যিক ডেটা বৈধতার জন্য যথেষ্ট:
// 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
দ্রুত ব্যর্থ হতে বা JSON.parse
ত্রুটিগুলি ধরতে / চেষ্টা করতে প্রসারিত হতে পারে ।
রাইটিং টাইপ গার্ড ফাংশনগুলি ম্যানুয়ালি জটিল হয়ে ওঠে, যদি আপনার অনেকগুলি বিভিন্ন মানকে বৈধতা দিতে হয়। এই কাজের সাথে সহায়তার জন্য গ্রন্থাগার রয়েছে - উদাহরণ (কোনও বিস্তৃত তালিকা নয়):
io-ts
: rel। জনপ্রিয় (বর্তমানে 3.2 কে তারা), fp-ts
পিয়ার নির্ভরতা, কার্যকরী প্রোগ্রামিং শৈলীzod
: একেবারে নতুন (repo: 2020-03-07), এর চেয়ে বেশি পদ্ধতিগত / অবজেক্ট-ভিত্তিক হতে চেষ্টা করেio-ts
typescript-is
: সংকলক এপিআই এর জন্য টিএস ট্রান্সফর্মার, টাইপ টাইপের জন্য অতিরিক্ত মোড়কের প্রয়োজনtypescript-json-schema
/ ajv
: প্রকার থেকে JSON স্কিমা তৈরি করুন এবং এটি দিয়ে বৈধতা দিনajv
আপনি যদি চান আপনার JSON এর বৈধতাযুক্ত টাইপসক্রিপ্টের ধরণ থাকে, তবে আপনাকে সেই বৈধতাটি নিজেই করতে হবে। এটি নতুন কিছু নয়। সরল জাভাস্ক্রিপ্টে আপনার একই কাজ করা দরকার।
আমি আমার বৈধতা যুক্তিটি "রূপান্তর" এর সেট হিসাবে প্রকাশ করতে চাই। আমি 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;
}
এখন, আমি কেবল আমার জেএসএন ইনপুটকে বৈধতা দিচ্ছি না, তবে আমি যেতে যেতে টাইপস্ক্রিপ্ট টাইপ তৈরি করছি। উপরের জেনেরিক প্রকারগুলি নিশ্চিত করে যে ফলাফলটি আপনার "রূপান্তর" থেকে প্রকারভেদগুলিকে অনুপ্রবেশ করে।
ট্রান্সফর্মটি যদি ত্রুটি ছুড়ে দেয় (তবে আপনি বৈধকরণটি কীভাবে প্রয়োগ করবেন), অন্য কোন ত্রুটিটি কী কারণে ত্রুটি ঘটেছে তা দেখিয়ে আমি এটিকে মোড়তে চাই।
আপনার উদাহরণে, আমি এটি নিম্নলিখিত হিসাবে ব্যবহার করব:
const value = pick(JSON.parse('{"name": "Bob", "error": false}'), {
name: String,
error: Boolean,
});
এখন value
টাইপ করা হবে, যেহেতু String
এবং Boolean
উভয়ই "ট্রান্সফরমার" অর্থে যে তারা ইনপুট নেয় এবং টাইপ করা আউটপুট ফেরত দেয়।
তদ্ব্যতীত, value
ইচ্ছার আসলে হতে যে প্রকার। অন্য কথায়, যদি name
আসলে থাকত তবে 123
এটি রূপান্তরিত হবে "123"
যাতে আপনার বৈধ স্ট্রিং থাকে। এটি কারণ আমরা String
রানটাইম ব্যবহার করি , একটি অন্তর্নির্মিত ফাংশন যা স্বেচ্ছাসেবিত ইনপুট গ্রহণ করে এবং a string
।
আপনি এখানে এটি কাজ দেখতে পারেন । নিজেকে বোঝাতে নিম্নলিখিত বিষয়গুলি চেষ্টা করুন:
const value
পপ-ওভারটি সঠিক ধরণটি দেখায় তা সংজ্ঞার উপরে ঘুরে দেখুন।"Bob"
করে 123
আবার চালানোর চেষ্টা করুন । আপনার কনসোলে আপনি দেখতে পাবেন যে নামটি স্ট্রিংয়ে সঠিকভাবে রূপান্তরিত হয়েছে "123"
।name
প্রকৃতপক্ষে থাকত তবে 123
এটি রূপান্তরিত হবে "123"
This এটি ভুল বলে মনে হচ্ছে I আমি যখন আপনার সমস্ত কোডটি value
{name: 123..
{name:"123"..
123
পরিবর্তে ব্যবহার করে "Bob"
)।
Transformed
ধরণের সংজ্ঞা দেওয়া দরকার । আপনি শুধু ব্যবহার করতে পারেন Object
। type Descriptor<T extends Object> = { ... };
Transformed
টাইপ সম্পূর্ণভাবে অপ্রয়োজনীয়। আমি সেই অনুযায়ী উত্তর আপডেট করেছি।
123
"123"
আপনি অতিরিক্তভাবে লাইব্রেরিগুলি ব্যবহার করতে পারেন যা আপনার জসনের প্রকারের বৈধতা সরবরাহ করে যেমন স্পার্কসন । তারা আপনাকে একটি টাইপস্ক্রিপ্ট শ্রেণি সংজ্ঞায়িত করার অনুমতি দেয়, যেখানে আপনি আপনার প্রতিক্রিয়া পার্স করতে চান, আপনার ক্ষেত্রে এটি হতে পারে:
import { Field } from "sparkson";
class Response {
constructor(
@Field("name") public name: string,
@Field("error") public error: boolean
) {}
}
প্রয়োজনীয় ক্ষেত্রগুলি JSON পে-লোডে উপস্থিত থাকলে এবং সেগুলির ধরণগুলি সঠিক হলে গ্রন্থাগারটি বৈধতা দেবে। এটি বৈধতা এবং রূপান্তরগুলির একটি গুচ্ছও করতে পারে।
এটির জন্য একটি দুর্দান্ত লাইব্রেরি রয়েছে ts-json-اعتراض
আপনার ক্ষেত্রে আপনাকে নিম্নলিখিত কোডটি চালনা করতে হবে:
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.parse
টাইপস্ক্রিপ্টে উপলভ্য, তাই আপনি কেবল এটি ব্যবহার করতে পারেন:
JSON.parse('{"name": "Bob", "error": false}') // Returns a value of type 'any'
যাইহোক, আপনি প্রায়শই কোনও ধরণের মানের সাথে আচরণের পরিবর্তে কোনও নির্দিষ্ট ধরণের সাথে মেলে কিনা তা নিশ্চিত করে একটি 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;
}
এই ফাংশনটিতে একটি জেএসওএন স্ট্রিং এবং একটি পৃথক ফাংশনযুক্ত একটি অবজেক্ট গ্রহণ করা হয় যা আপনি তৈরি করছেন এমন প্রতিটি ক্ষেত্র লোড করে load আপনি এটি এর মতো ব্যবহার করতে পারেন:
const value = parse_json(
'{"name": "Bob", "error": false}',
{ name: String, error: Boolean, }
);
টাইপস্রিপ্টের একটি জাভাস্ক্রিপ্ট রানটাইম রয়েছে কারণ এটি জেএসে সংকলিত হয়ে যায়। এই উপায়ে জাতীয় বস্তু যা যেমন ভাষা অংশ হিসেবে আগে থেকেই রয়েছে JSON
, Object
এবং Math
হিজড়া মধ্যে উপলব্ধ রয়েছে। সুতরাং আমরা কেবল JSON.parse
JSON স্ট্রিংকে বিশ্লেষণের জন্য পদ্ধতিটি ব্যবহার করতে পারি ।
const JSONStr = '{"name": "Bob", "error": false}'
// The JSON object is part of the runtime
const parsedObj = JSON.parse(JSONStr);
console.log(parsedObj);
// [LOG]: {
// "name": "Bob",
// "error": false
// }
// The Object object is also part of the runtime so we can use it in TS
const objKeys = Object.keys(parsedObj);
console.log(objKeys);
// [LOG]: ["name", "error"]
এখন কেবলমাত্র জিনিসটি পার্সডওবজ টাইপ any
যা সাধারণত টিএসে একটি খারাপ অভ্যাস। আমরা যদি প্রকারের প্রহরী ব্যবহার করে থাকি তবে আমরা বস্তুটি টাইপ করতে পারি। এখানে একটি উদাহরণ:
const JSONStr = '{"name": "Bob", "error": false}'
const parsedObj = JSON.parse(JSONStr);
interface nameErr {
name: string;
error: boolean;
}
function isNameErr(arg: any): arg is nameErr {
if (typeof arg.name === 'string' && typeof arg.error === 'boolean') {
return true;
} else {
return false;
}
}
if (isNameErr(parsedObj)) {
// Within this if statement parsedObj is type nameErr;
parsedObj
}