কীভাবে JSON স্ট্রিংকে টাইপস্ক্রিপ্টে পার্স করবেন


111

টাইপসক্রিপ্টে JSON হিসাবে স্ট্রিংকে বিশ্লেষণ করার কোনও উপায় আছে কি?
উদাহরণ: জেএসে, আমরা ব্যবহার করতে পারি JSON.parse()। টাইপস্ক্রিপ্টে কি একই রকম ফাংশন রয়েছে?

আমার নীচে JSON অবজেক্ট স্ট্রিং রয়েছে:

{"name": "Bob", "error": false}

4
এর হোমপৃষ্ঠায় এটি বলে যে "টাইপস্ক্রিপ্টটি জাভাস্ক্রিপ্টের একটি টাইপ করা সুপারসেট যা সাধারণ জাভাস্ক্রিপ্টকে সংকলন করে"। JSON.parse () ফাংশনটি স্বাভাবিকের মতো ব্যবহারযোগ্য হওয়া উচিত।
সিগালোর

4
আমি এটম টেক্সট এডিটরটি ব্যবহার করছি এবং আমি যখন JSON.parse করি তখন ত্রুটিটি পাওয়া যায়: '{}' টাইপের
যুক্তিটি

23
এটি একটি খুব বেসিক প্রশ্ন এবং এটি কারও কাছে তুচ্ছ মনে হতে পারে তবে এটি একটি বৈধ প্রশ্ন কম নয়, এবং সমমানের বিষয়টি এসও-তে পাওয়া যায় না (আমি নেই) সুতরাং প্রশ্ন না রাখার বাস্তব কারণ নেই চলমান, এবং আমার মতে পাশাপাশি ভোট দেওয়া উচিত নয়।
নিতজান টোমর

4
@ সংকেতদেশপাণ্ডে আপনি যখন ব্যবহার করবেন JSON.parseআপনি ফলাফল হিসাবে একটি বস্তু পাবেন এবং একটি নয় string(আরও উত্তর দেওয়ার জন্য আমার উত্তর দেখুন)। আপনি যদি কোনও বস্তুকে স্ট্রিংয়ে রূপান্তর করতে চান তবে তার JSON.stringifyপরিবর্তে আপনার প্রয়োজন ।
নিতজান টোমর

4
আসলে এটি 2 কারণে সাধারণ প্রশ্ন নয়। প্রথমত, JSON.parse () একই ধরণের বস্তুটি ফিরিয়ে দেয় না - এটি কিছু ইন্টারফেসের সাথে মেলে তবে কিছু বুদ্ধিমান, যেমন অ্যাকসেসর উপস্থিত থাকবে না। তদ্ব্যতীত, অবশ্যই আমরা চাই লোকেরা যেখানে স্টাফ গুগল করে সেখানে যায়?
প্রজাতি অজানা

উত্তর:


184

প্রকারভেদটি জাভাস্ক্রিপ্ট (একটি সুপারসেট), তাই আপনি জাভাস্ক্রিপ্টে 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);

( খেলার মাঠে কোড )


10
ইনপুটটি বৈধ কিনা তা যাচাই করবেন (টাইপ-চেকিং, টাইপস্ক্রিপ্টের অন্যতম উদ্দেশ্য)? '{ "myString": "string", "myNumber": 4 }'দ্বারা ইনপুট প্রতিস্থাপন '{ "myString": "string", "myNumberBAD": 4 }'ব্যর্থ হবে না, এবং obj.myNumber অপরিবর্তিত ফিরে আসবে।
ডেভিড পোর্টাবেলা

4
@ ডেভিডপোর্টাবেলা আপনার কাছে স্ট্রিংয়ের বিষয়বস্তুতে টাইপ-চেকিং থাকতে পারে না। এটি একটি রানটাইম সমস্যা, এবং টাইপ চেকিং সংকলন সময়ের জন্য
নিতজান টোমর

4
ঠিক আছে. আমি কীভাবে যাচাই করতে পারি যে কোনও টাইপ স্ক্রিপ্ট আপজ রানটাইমের সময় তার ইন্টারফেসটিকে সন্তুষ্ট করে? যে, এই উদাহরণে মাই নাম্বার অপরিজ্ঞাত নয়। উদাহরণস্বরূপ, স্কেলা প্লেতে আপনি ব্যবহার করবেন Json.parse(text).validate[MyObj]playframework.com/docamentation/2.6.x/ScalaJson আপনি টাইপস্ক্রিপ্টে কীভাবে এটি করতে পারেন (সম্ভবত এটি করার জন্য কোনও বাহ্যিক গ্রন্থাগার রয়েছে?)?
ডেভিড পোর্টাবেলা

4
@ ডেভিডপোর্টাবেলা এটি করার কোনও উপায় নেই, সহজেই নয়, কারণ রানটাইমের সময় MyObjউপস্থিত নেই। এই বিষয়টি সম্পর্কে এসও তে প্রচুর অন্যান্য থ্রেড রয়েছে, উদাহরণস্বরূপ: কোনও বস্তু টাইপস্ক্রিপ্ট সহ রানটাইমের সময় একটি ইন্টারফেস প্রয়োগ করে কিনা তা পরীক্ষা করুন
নিতজান টোমর

7
ঠিক আছে ধন্যবাদ. প্রতিদিন আমি স্কেলাজ ব্যবহার সম্পর্কে আরও দৃ am়প্রত্যয়ী।
ডেভিড পোর্টাবেলা

8

টাইপ-সেফ JSON.parse

JSON.parseটিএস হ'ল জেএস সুপারসেট হিসাবে আপনি ব্যবহার চালিয়ে যেতে পারেন । এখনও একটি সমস্যা বাকি আছে: JSON.parseরিটার্ন 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দ্রুত ব্যর্থ হতে বা JSON.parseত্রুটিগুলি ধরতে / চেষ্টা করতে প্রসারিত হতে পারে ।

২. বাহ্যিক গ্রন্থাগার

রাইটিং টাইপ গার্ড ফাংশনগুলি ম্যানুয়ালি জটিল হয়ে ওঠে, যদি আপনার অনেকগুলি বিভিন্ন মানকে বৈধতা দিতে হয়। এই কাজের সাথে সহায়তার জন্য গ্রন্থাগার রয়েছে - উদাহরণ (কোনও বিস্তৃত তালিকা নয়):

  • io-ts: rel। জনপ্রিয় (বর্তমানে 3.2 কে তারা), fp-tsপিয়ার নির্ভরতা, কার্যকরী প্রোগ্রামিং শৈলী
  • zod: একেবারে নতুন (repo: 2020-03-07), এর চেয়ে বেশি পদ্ধতিগত / অবজেক্ট-ভিত্তিক হতে চেষ্টা করেio-ts
  • typescript-is: সংকলক এপিআই এর জন্য টিএস ট্রান্সফর্মার, টাইপ টাইপের জন্য অতিরিক্ত মোড়কের প্রয়োজন
  • typescript-json-schema/ ajv: প্রকার থেকে JSON স্কিমা তৈরি করুন এবং এটি দিয়ে বৈধতা দিনajv

আরও ইনফো


4

আপনি যদি চান আপনার 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"..
ঠিকভাবে

অদ্ভুত, এটি আমার জন্য কাজ করে। এটি এখানে চেষ্টা করুন: typcriptlang.org/play/index.html ( 123পরিবর্তে ব্যবহার করে "Bob")।
চৌই

আমি মনে করি না আপনার কোনও Transformedধরণের সংজ্ঞা দেওয়া দরকার । আপনি শুধু ব্যবহার করতে পারেন Objecttype Descriptor<T extends Object> = { ... };
লোভাসোয়া

ধন্যবাদ @ লভোসোয়া, আপনি সঠিক বলেছেন। Transformedটাইপ সম্পূর্ণভাবে অপ্রয়োজনীয়। আমি সেই অনুযায়ী উত্তর আপডেট করেছি।
চৌই

আপনি যদি যাচাই করতে চান যে JSON অবজেক্টের সঠিক প্রকার রয়েছে, আপনি স্বয়ংক্রিয়ভাবে একটি স্ট্রিংয়ে রূপান্তর করতে চান না , কারণ এটি JSON অবজেক্টের একটি সংখ্যা। 123"123"
xuiqzy

1

আপনি অতিরিক্তভাবে লাইব্রেরিগুলি ব্যবহার করতে পারেন যা আপনার জসনের প্রকারের বৈধতা সরবরাহ করে যেমন স্পার্কসন । তারা আপনাকে একটি টাইপস্ক্রিপ্ট শ্রেণি সংজ্ঞায়িত করার অনুমতি দেয়, যেখানে আপনি আপনার প্রতিক্রিয়া পার্স করতে চান, আপনার ক্ষেত্রে এটি হতে পারে:

import { Field } from "sparkson";
class Response {
   constructor(
      @Field("name") public name: string,
      @Field("error") public error: boolean
   ) {}
}

প্রয়োজনীয় ক্ষেত্রগুলি JSON পে-লোডে উপস্থিত থাকলে এবং সেগুলির ধরণগুলি সঠিক হলে গ্রন্থাগারটি বৈধতা দেবে। এটি বৈধতা এবং রূপান্তরগুলির একটি গুচ্ছও করতে পারে।


4
আপনার উল্লেখ করা উচিত, আপনি উপরের লাইব্রেরির প্রধান অবদানকারী।
ford04

1

এটির জন্য একটি দুর্দান্ত লাইব্রেরি রয়েছে 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});

এই পাঠাগারটি পার্স করার আগে জসনকে বৈধতা দেবে


0

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, }
);

0

টিএসের একটি জাভাস্ক্রিপ্ট রানটাইম রয়েছে

টাইপস্রিপ্টের একটি জাভাস্ক্রিপ্ট রানটাইম রয়েছে কারণ এটি জেএসে সংকলিত হয়ে যায়। এই উপায়ে জাতীয় বস্তু যা যেমন ভাষা অংশ হিসেবে আগে থেকেই রয়েছে JSON, Objectএবং Mathহিজড়া মধ্যে উপলব্ধ রয়েছে। সুতরাং আমরা কেবল JSON.parseJSON স্ট্রিংকে বিশ্লেষণের জন্য পদ্ধতিটি ব্যবহার করতে পারি ।

উদাহরণ:

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
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.