টাইপস্ক্রিপ্ট টাইপ 'স্ট্রিং' টাইপ করার যোগ্য নয়


161

আমার ফল যা আছে তা এখানে

export type Fruit = "Orange" | "Apple" | "Banana"

এখন আমি অন্য টাইপ স্ক্রিপ্ট ফাইলে ফলের.টি আমদানি করছি। আমার যা আছে তা এখানে

myString:string = "Banana";

myFruit:Fruit = myString;

যখন আমি করি

myFruit = myString;

আমি একটি ত্রুটি পেয়েছি:

টাইপ 'স্ট্রিং' টাইপ করতে "" কমলা "| "আপেল" | "কলা" '

আমি কীভাবে কাস্টম টাইপের ফলের একটি পরিবর্তনশীলকে একটি স্ট্রিং বরাদ্দ করতে পারি?


1
আপনি একক এবং ডাবল উদ্ধৃতি ব্যবহার সম্পর্কে যথেষ্ট নিশ্চিত export type Fruit?
আবহাওয়া ভেন

1
@ ওয়েদারভেন সবেমাত্র আমার ফ্রুট.টি. রফতানির জন্য আমার কাছে সেখানে একক উক্তি রয়েছে = 'কমলা' || 'আপেল' || 'কলা'। ধন্যবাদ
ব্যবহারকারী 6123723

এখনও আমার কাছে কিছু ডাবল উদ্ধৃতি বলে মনে হচ্ছে ...
আবহাওয়া ভেন

উত্তর:


231

আপনার এটি কাস্ট করতে হবে :

export type Fruit = "Orange" | "Apple" | "Banana";
let myString: string = "Banana";

let myFruit: Fruit = myString as Fruit;

এছাড়াও লক্ষ করুন যে স্ট্রিং লিটারালগুলি ব্যবহার করার সময় আপনার কেবল একটি ব্যবহার করা দরকার|

সম্পাদন করা

@ সিমন_উইভারের অন্যান্য উত্তরে যেমন উল্লেখ করা হয়েছে, এখন এটির পক্ষে এটি দৃ to় করা সম্ভব const:

let fruit = "Banana" as const;

11
বেশ ভাল :) বেশিরভাগ ক্ষেত্রেই const myFruit: Fruit = "Banana"তা করত।
জ্যাকা

আমি কি এর বিপরীত কাজ করতে পারি? আমি এর অর্থ কিছু বোঝাতে চাইছি let myFruit:Fruit = "Apple" let something:string = myFruit as string এটি আমাকে ত্রুটি দিচ্ছে: 'স্ট্রিং' টাইপ করতে 'ফল' টাইপের রূপান্তরটি একটি ভুল হতে পারে।
সিরাজ আলম

@ সিরাজ এটি ঠিকভাবে কাজ করা উচিত, আপনি এমনকি as stringঅংশ প্রয়োজন হয় না । আমি খেলার মাঠে আপনার কোড চেষ্টা করেছি এবং কোনও ত্রুটি নেই।
নিতজান টোমার

@NitzanTomer stackoverflow.com/questions/53813188/... আমার বিস্তারিত প্রশ্ন তাকান
সিরাজ আলম

তবে এখন যদি টাইপ const myString: string = 'Bananaaa'; করি আমি কাস্টিংয়ের কারণে সংকলন ত্রুটিগুলি পাই না ... স্ট্রিং পরীক্ষা করার সময় এটি করার কোনও উপায় নেই?
ব্লু

66

টাইপস্ক্রিপ্ট 3.4নতুন ' কনস্ট ' দৃ'়তার পরিচয় দেয়

আপনি এখন আক্ষরিক ধরণের (যেমন। 'orange'বা 'red') stringতথাকথিত constদৃ as়তার সাথে টাইপ করতে 'প্রশস্ত' হওয়া রোধ করতে পারেন ।

আপনি করতে সক্ষম হবেন:

let fruit = 'orange' as const;  // or...
let fruit = <const> 'orange';

এবং তারপরে এটি নিজেকে stringআর রূপান্তরিত করবে না - যা প্রশ্নের সমস্যার মূল।


আমার মতো লোকেরা, এখনও 3.4-তে নেই। <const> যে কোনও দ্বারা প্রতিস্থাপন করা যেতে পারে, তবে অবশ্যই এই সমাধানের মতো পরিষ্কার নয়।
পিটার ডি বিয়

2
let fruit = 'orange' as const;নো-এঙ্গেল-বন্ধনী-প্রকার-
দৃ as়

2
এটি আধুনিক টাইপস্ক্রিপ্টের সঠিক উত্তর। এটি প্রকারের অপ্রয়োজনীয় আমদানি রোধ করে এবং কাঠামোগত টাইপিংকে এটি সঠিকভাবে করতে দেয়।
জেমস ম্যাকমাহন

24

আপনি যখন এটি করবেন:

export type Fruit = "Orange" | "Apple" | "Banana"

... আপনি একটি ধরণের নাম তৈরি করছেন Fruitযা কেবল আক্ষরিক "Orange", "Apple"এবং "Banana"। এই প্রকারটি প্রসারিত String, সুতরাং এটি নির্ধারিত হতে পারে String। যাইহোক, Stringপ্রসারিত হয় না "Orange" | "Apple" | "Banana", তাই এটি এটি বরাদ্দ করা যাবে না। Stringহয় কম সুনির্দিষ্ট । এটি যে কোনও স্ট্রিং হতে পারে ।

আপনি যখন এটি করবেন:

export type Fruit = "Orange" | "Apple" | "Banana"

const myString = "Banana";

const myFruit: Fruit = myString;

... এটি কাজ করে। কেন? কারণ প্রকৃত টাইপ এর myStringএই উদাহরণে হয় "Banana"। হ্যাঁ, "Banana"হয় টাইপ । এটি প্রসারিত Stringতাই এটি নির্ধারিত হয় String। অতিরিক্তভাবে, কোনও প্রকার ইউনিয়ন প্রকারকে প্রসারিত করে যখন এটির যে কোনও উপাদান প্রসারিত করে । এই ক্ষেত্রে, "Banana"প্রকারটি প্রসারিত হয় "Orange" | "Apple" | "Banana"কারণ এটি এর একটি উপাদানকে প্রসারিত করে। অতএব, "Banana"নিযুক্ত "Orange" | "Apple" | "Banana"বা হয় Fruit


2
এটি মজার যে আপনি আসলে রাখতে পারেন <'Banana'> 'Banana'এবং এটি "Banana"স্ট্রিংটিকে 'কাস্ট' করে দেবে "Banana"!!!
সাইমন_ ওয়েভার

2
তবে এখন আপনি <const> 'Banana'যা আরও ভাল তা করতে পারেন :-)
সাইমন_উইভার

11

আমি দেখতে এটি কিছুটা পুরানো, তবে এখানে আরও ভাল সমাধান হতে পারে।

আপনি যখন একটি স্ট্রিং চান, তবে আপনি স্ট্রিংটি কেবলমাত্র নির্দিষ্ট মানের সাথে মেলে তা চান, আপনি এনাম ব্যবহার করতে পারেন ।

উদাহরণ স্বরূপ:

enum Fruit {
    Orange = "Orange",
    Apple  = "Apple",
    Banana = "Banana"
}

let myFruit: Fruit = Fruit.Banana;

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


1
এটি মজার কারণ কারণ এটি থেকে দূরে থাকার চেষ্টা করার সময় আমি এই সমস্যাটি পাই। এটা ক্রমশ আমার বাদাম চালাচ্ছে। আমি 'জাভাস্ক্রিপ্টি' হওয়ার চেষ্টা করছি এবং ম্যাজিক স্ট্রিংগুলি একটি ধরণের (একটি গণনার পরিবর্তে) সীমাবদ্ধভাবে ব্যবহার করার চেষ্টা করছি এবং এটি আরও বেশি করে ব্যাকফায়ার হতে পারে এবং এই ত্রুটিটি সহ আমার পুরো অ্যাপ্লিকেশনটির মধ্যে
ছড়িয়ে পড়েছে

1
এর ফলে বিপরীত সমস্যাও হয়। আপনি আর করতে পারবেন না let myFruit: Fruit = "Banana"
সান বার্টন

11

বেশ কয়েকটি পরিস্থিতি রয়েছে যা আপনাকে এই বিশেষ ত্রুটিটি দেবে। ওপির ক্ষেত্রে স্ট্রিং হিসাবে স্পষ্টভাবে সংজ্ঞায়িত একটি মান ছিল । সুতরাং আমি ধরে নিতে হবে যে এটি সম্ভবত একটি ড্রপডাউন, বা ওয়েব পরিষেবা বা কাঁচা জেএসএন স্ট্রিং থেকে এসেছে।

সেক্ষেত্রে একটি সাধারণ castালাই <Fruit> fruitStringবা fruitString as Fruitএটিই একমাত্র সমাধান (অন্যান্য উত্তর দেখুন)। সংকলনের সময় আপনি কখনই এটিতে উন্নতি করতে পারবেন না। [ সম্পাদনা: সম্পর্কে আমার অন্যান্য উত্তর দেখুন<const> ]!

তবে এটি খুব সহজ যখন আপনার কোডে ধ্রুবক যে ব্যবহার করে এই একই ত্রুটির মধ্যে চালানোর জন্য এর কি কখনো টাইপ স্ট্রিং হতে উদ্দেশ্যে না হয় । আমার উত্তরটি সেই দ্বিতীয় দৃশ্যের উপর আলোকপাত করে:


প্রথমত: 'ম্যাজিক' স্ট্রিং ধ্রুবকগুলি প্রায়শই এনামের চেয়ে ভাল কেন হয়?

  • আমি যেমন একটি স্ট্রিং ধ্রুবকটিকে বনাম বনাম দেখায় পছন্দ করি - এটি কমপ্যাক্ট এবং 'জাভাস্ক্রিপ্টি'
  • আপনি যে উপাদানটি ইতিমধ্যে ব্যবহার করছেন সেগুলি যদি স্ট্রিং ধ্রুবক ব্যবহার করে তবে আরও অর্থবোধ তৈরি করে।
  • কেবল একটি গণনার মান পেতে একটি 'এনাম টাইপ' আমদানি করা নিজের মধ্যে ঝামেলা হতে পারে
  • আমি যাই করুক না কেন আমি এটি নিরাপদ সংকলন করতে চাই তাই আমি যদি ইউনিয়নের ধরণ থেকে কোনও বৈধ মান মুছে ফেলি, বা এটি ভুল টাইপ করি তবে এটি অবশ্যই একটি সংকলন ত্রুটি দেবে।

ভাগ্যক্রমে আপনি সংজ্ঞায়িত যখন:

export type FieldErrorType = 'none' | 'missing' | 'invalid'

... আপনি আসলে একটি সংজ্ঞায়িত করছি ধরনের ইউনিয়ন যেখানে 'missing'আসলে একটি টাইপ হয়!

'banana'আমার টাইপস্ক্রিপ্টের মতো স্ট্রিং থাকলে আমি প্রায়শই 'অ্যাসাইনেবল' ত্রুটিতে চলে যাই এবং সংকলকটি মনে করে আমি এটি একটি স্ট্রিং হিসাবে বোঝাতে চাইছি, আমি সত্যই এটি টাইপ হতে চেয়েছিলাম banana। সংকলকটি কতটা স্মার্ট হতে সক্ষম তা আপনার কোডের কাঠামোর উপর নির্ভর করবে।

আজ যখন আমি এই ত্রুটিটি পেয়েছি তার একটি উদাহরণ এখানে:

// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]

যত তাড়াতাড়ি আমি এটি জানতে পেরেছি 'invalid'বা 'banana'হয় হয় টাইপ বা একটি স্ট্রিং হতে পারে আমি বুঝতে পারি যে আমি কেবল সেই ধরণের মধ্যে একটি স্ট্রিং যুক্ত করতে পারি । মূলত এটিকে নিজের কাছে ফেলে দিন এবং সংকলককে বলুন আমি চাই না এটি স্ট্রিং হয়ে উঠুক !

// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]

সুতরাং FieldErrorType(বা Fruit) কেবল 'castালাই' দিয়ে কী সমস্যা হয়েছে?

// why not do this?
fieldErrors: [ { fieldName: 'number', error: <FieldErrorType> 'invalid' } ]

এটি নিরাপদ সময় নিরাপদ নয়:

 <FieldErrorType> 'invalidddd';  // COMPILER ALLOWS THIS - NOT GOOD!
 <FieldErrorType> 'dog';         // COMPILER ALLOWS THIS - NOT GOOD!
 'dog' as FieldErrorType;        // COMPILER ALLOWS THIS - NOT GOOD!

কেন? এটি টাইপস্ক্রিপ্ট তাই একটি জোর দেওয়া<FieldErrorType> এবং আপনি সংকলককে বলছেন একটি কুকুর একটি ফিল্ডআররটাইপ ! এবং সংকলক এটি অনুমতি দেবে!

তবে আপনি যদি নিম্নলিখিতটি করেন তবে সংকলক স্ট্রিংটিকে কোনও প্রকারে রূপান্তর করবে

 <'invalid'> 'invalid';     // THIS IS OK  - GOOD
 <'banana'> 'banana';       // THIS IS OK  - GOOD
 <'invalid'> 'invalidddd';  // ERROR       - GOOD
 <'dog'> 'dog';             // ERROR       - GOOD

এইরকম বোকা টাইপগুলি সন্ধান করুন:

 <'banana'> 'banan';    // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!

সমস্যাটি সমাধানের আরেকটি উপায় হ'ল প্যারেন্ট অবজেক্টটি ingালাই:

আমার সংজ্ঞাগুলি নিম্নরূপ ছিল:

রফতানির প্রকার FieldName = 'সংখ্যা' | 'এক্সপায়ারডেট' | 'CVV'; রফতানির ধরন FieldError = 'কিছুই নয়' 'নিখোঁজ' | 'অবৈধ'; রফতানির ধরন ফিল্ডেররর টাইপ = {ক্ষেত্র: ক্ষেত্রের নাম, ত্রুটি: ফিল্ডআরর};

ধরা যাক আমরা এটির সাথে একটি ত্রুটি পেয়েছি (স্ট্রিংটি নির্ধারণযোগ্য ত্রুটিটি নয়):

  fieldErrors: [ { field: 'number', error: 'invalid' } ]

আমরা পুরো অবজেক্টকে এর মতো 'দৃ as়' করতে পারি FieldErrorType:

  fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]

তারপরে আমরা করণীয় এড়িয়ে চলি <'invalid'> 'invalid'

তবে টাইপসের কী হবে? যে ধরণের হতে পারে ডানদিকে যা আছে তা <FieldErrorType>কেবল জোড় করে না। না এই ক্ষেত্রে - সৌভাগ্যবশত কম্পাইলার হবে অভিযোগ যদি আপনি এই কাজ করতে, কারণ এটি এটা অসম্ভব জানেন যে চালাক যথেষ্ট:

  fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]

কঠোর মোডের সাথে সূক্ষ্মতা থাকতে পারে। নিশ্চিত হওয়ার পরে উত্তর আপডেট করবে।
সাইমন_ ওয়েভার

1

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

  // in foo.ts
  export type ToolbarTheme = {
    size: 'large' | 'small',
  };

  // in bar.ts
  import { ToolbarTheme } from './foo.ts';
  function useToolbarTheme(theme: ToolbarTheme) {/* ... */}

  // Here you will get the following error: 
  // Type 'string' is not assignable to type '"small" | "large"'.ts(2322)
  ['large', 'small'].forEach(size => (
    useToolbarTheme({ size })
  ));

এটি ঠিক করার জন্য আপনার একাধিক সমাধান রয়েছে। প্রতিটি সমাধান বৈধ এবং এর নিজস্ব ব্যবহারের কেস রয়েছে।

1) প্রথম সমাধানটি আকারের জন্য কোনও ধরণের সংজ্ঞা দেওয়া এবং foo.ts থেকে রফতানি করা to এটি যখন আপনার নিজের আকারের প্যারামিটার দিয়ে কাজ করার দরকার হয় তখন এটি ভাল। উদাহরণস্বরূপ, আপনার একটি ফাংশন রয়েছে যা টাইপ আকারের একটি প্যারামিটার গ্রহণ করে বা প্রদান করে এবং আপনি এটি টাইপ করতে চান।

  // in foo.ts
  export type ToolbarThemeSize = 'large' | 'small';
  export type ToolbarTheme = {
    size: ToolbarThemeSize
  };

  // in bar.ts
  import { ToolbarTheme, ToolbarThemeSize } from './foo.ts';
  function useToolbarTheme(theme: ToolbarTheme) {/* ... */}
  function getToolbarSize(): ToolbarThemeSize  {/* ... */}

  ['large', 'small'].forEach(size => (
    useToolbarTheme({ size: size as ToolbarThemeSize })
  ));

2) দ্বিতীয় বিকল্পটি কেবল এটিকে টাইপ করে সরঞ্জামদন্ডে থিম। এই ক্ষেত্রে, আপনার প্রয়োজন না থাকলে আপনার সরঞ্জামদণ্ডের অভ্যন্তরীণ অংশটি প্রকাশ করার দরকার নেই exp

  // in foo.ts
  export type ToolbarTheme = {
    size: 'large' | 'small'
  };

  // in bar.ts
  import { ToolbarTheme } from './foo.ts';
  function useToolbarTheme(theme: ToolbarTheme) {/* ... */}

  ['large', 'small'].forEach(size => (
    useToolbarTheme({ size } as ToolbarTheme)
  ));

0

আপনি dropdownvalue[]উদাহরণস্বরূপ ডেটা উপহাস করার সময় যদি কাস্টিং করছেন তবে মান এবং প্রদর্শনের বৈশিষ্ট্যযুক্ত বস্তুর অ্যারে হিসাবে এটি রচনা করুন।

উদাহরণ :

[{'value': 'test1', 'display1': 'test display'},{'value': 'test2', 'display': 'test display2'},]

0

আমি একই সমস্যার মুখোমুখি হয়েছি, আমি নীচে পরিবর্তনগুলি করেছি এবং সমস্যাটি সমাধান হয়ে গেছে।

WatchQueryOptions.d.ts ফাইল খুলুন

\apollo-client\core\watchQueryOptions.d.ts

ক্যোয়ারী টাইপ পরিবর্তন কোনো পরিবর্তে DocumentNode , পরিবর্তন জন্য একই

আগে:

export interface QueryBaseOptions<TVariables = OperationVariables> {
    query: **DocumentNode**;

পরে:

export interface QueryBaseOptions<TVariables = OperationVariables> {
    query: **any**;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.