কীভাবে "ত্রুটি টিএস 25৩৩ টি দমন করবেন: অবজেক্টটি সম্ভবত 'নাল' বা 'অপরিজ্ঞাত'?


225

আমার একটি আছে type:

type tSelectProtected = {
  handleSelector?: string,
  data?: tSelectDataItem[],

  wrapperEle?: HTMLElement,
  inputEle?: HTMLElement,
  listEle?: HTMLElement,
  resultEle?: HTMLElement,

  maxVisibleListItems?: number
}

আমি একটি বিশ্বব্যাপী মডিউল-ভিত্তিক ভেরিয়েবল ঘোষণা করি:

var $protected : tSelectProtected = {};

আমি function1()সুযোগে যথাযথ মান নির্ধারণ করছি :

$protected.listEle = document.createElement('DIV');

function2()সুযোগ পরে , আমি কল করছি:

$protected.listEle.classList.add('visible');

আমি টাইপস্ক্রিপ্ট ত্রুটি পেয়েছি:

error TS2533: Object is possibly 'null' or 'undefined'

আমি জানি যে if ($protected.listEle) {$protected.listEle}সংকলককে শান্ত করার জন্য আমি স্পষ্টত চেক করতে পারি তবে এটি বেশিরভাগ নন মামুলির ক্ষেত্রে খুব অযৌক্তিক বলে মনে হয়।

টিএস সংকলক চেক অক্ষম না করে এই পরিস্থিতি কীভাবে পরিচালনা করা উচিত?

উত্তর:


99

এই বৈশিষ্ট্যটিকে "কঠোর নাল চেকস" বলা হয়, এটি বন্ধ করে রাখার জন্য যাতে --strictNullChecksকম্পাইলার পতাকাটি সেট করা না থাকে তা নিশ্চিত করে ।

তবে এর অস্তিত্বটিকে বিলিয়ন ডলার ত্রুটি হিসাবে বর্ণনাnull করা হয়েছে , সুতরাং টাইপসক্রিপ্টের মতো কোনও ভাষা স্থিরকরণের মতো ভাষা দেখতে আকর্ষণীয় হয়। আমি এটি চালু রাখার জন্য দৃ recommend়ভাবে সুপারিশ করব।

এটির সমাধানের একটি উপায় হ'ল মানগুলি কখনই না হয় তা নিশ্চিত করা nullবা undefinedউদাহরণস্বরূপ এগুলি সামনের দিকে শুরু করে:

interface SelectProtected {
    readonly wrapperElement: HTMLDivElement;
    readonly inputElement: HTMLInputElement;
}

const selectProtected: SelectProtected = {
    wrapperElement: document.createElement("div"),
    inputElement: document.createElement("input")
};

যদিও বিকল্প বিকল্পের জন্য রায়ান কাভানফের উত্তর দেখুন!


8
nullভেরিয়েবল বা বৈশিষ্ট্যের মানগুলি আরম্ভ করার জন্য ব্যক্তিগতভাবে আমি "ভ্যানিলা" জাভাস্ক্রিপ্টে ব্যবহার করি । প্রদত্ত ভের বা প্রপ উপস্থিত থাকলে এটি আমাকে সোজা উত্তর দেয় তবে এটির "কোনও ব্যবহারযোগ্য মান নেই" বা "কার্যকর হওয়ার কোনও সময়ে মানটি সাফ করা হয়েছিল"। এটা ঠিক কনভেনশন দ্বারা। এটি টাইপস্ক্রিপ্টে সেরা পন্থা নাও হতে পারে কারণ আমি এখানে উত্তর দিয়ে দেখতে পারি। আপনার ভাবনার জন্য আপনাকে ধন্যবাদ.
— গ্রাসনাল


1
হ্যাঁ, তবে এই সংজ্ঞাগুলি অবজেক্টের মান পরিবর্তন করে, উদাহরণস্বরূপ, এইচটিএমএলডিভেলিমেন্টের নিকটতম লক্ষ্য এবং অন্যান্য মৌলিক উপাদান ইভেন্ট এবং বৈশিষ্ট্য নেই।
— ক্লারেন্স

5
আপনি যদি কিছু জাভাস্ক্রিপ্ট অবজেক্ট সম্পত্তি সম্পর্কিত একটি রাজ্য বর্ণনা করার চেষ্টা করছেন, যেখানে প্রারম্ভিক রাষ্ট্রটির সত্য উপস্থাপনা null?
— তৈমুর মমেদভ

1
!কোটলিনের মতো অপারেটর রয়েছে এমন একটি অপারেটর যোগ করার সাথে সাথে আপনি এই চেকগুলিকে আরও সংক্ষিপ্ত করে তুলতে পারবেন
— আলভারো

598

আপনি যদি বাহ্যিক অর্থ থেকে জানেন যে কোনও অভিব্যক্তিটি নয় nullবা undefined, আপনি !এই ধরণের চাপ দেওয়ার জন্য নন-নাল অ্যাডরেন্স অপারেটরটি ব্যবহার করতে পারেন :

// Error, some.expr may be null or undefined
let x = some.expr.thing;
// OK
let y = some.expr!.thing;

12
! - Non-null assertion operatorঅপারেটর সম্পর্কে আমাকে জানানোর জন্য ধন্যবাদ । দেখে মনে হচ্ছে জিনিসটি এখনও ভালভাবে নথিভুক্ত হয়নি ( https://github.com/Mic Microsoft/TypeScript/issues/11494
— -পরে

9
এটি টিএসসি v2.7.2- এ আমার জন্য কোনও প্রভাব ফেলবে না
— Tyguy7

6
@ThomasSauvajon !অপারেটর এখানে নেই না হিসাবে একই জিনিস করে ?সি # আছে! এটি কেবলমাত্র একটি টাইপ সিস্টেমের দাবি; nullবা থেকে কোনও সম্পত্তি পড়ার চেষ্টা করার সময় এটি আপনার প্রোগ্রামটিকে ক্রাশ না করবে undefined।
— রায়ান কাভানফো

2
হ্যান্ডবুক থেকে, রায়ের প্রডিংয়ে যুক্ত হয়েছে: সিনট্যাক্সটি পোস্টফিক্স !: identifier!সরিয়ে দেয় nullএবং undefinedএর ধরণ থেকেidentifier রায়ান যা ইতিমধ্যে বলেছিল, তবে আমি এটিও সহায়ক বলে মনে করি।
— জন হ্যাটন

5
এটি টাইপস্ক্রিপ্ট 3.2.2 এ কাজ করে না। এটি সরানো হয়েছে?
— লার্স ন্যাস্ট্রোম

25

আমি ব্যবহার করতাম:

if (object !== undefined) {
    // continue - error suppressed when used in this way.
}

বিকল্পভাবে, আপনি ধরণের দমন ব্যবহার করতে পারেন:

const objectX = object as string

যদিও উপরোক্ত কাজের ক্ষেত্রগুলির মধ্যে একটি চয়ন করার আগে, দয়া করে আপনি যে আর্কিটেকচারটি লক্ষ্য করছেন সেটি বিবেচনা করুন এবং এটি আরও বড় ছবিতে প্রভাব ফেলবে।


57
কোনও কারণে আমার টিএসসি উপেক্ষা করে যে যদি বিবৃতিটি এখনও থাকে তবে এটি সম্ভবত সম্ভাব্য অপরিবর্তিত হিসাবে বিবেচনা করে ...
— টাইগ্য

9
আমি যখন ব্যবহার করি তখন আমার ত্রুটিটি দমন করা হয় নাif(object!==undefined) object.function();
— জার্মি

কেউ nullএবং এর সাথে দ্বিগুণ undefinedতুলনাও ব্যবহার করতে পারে এবং এটি কোনও খারাপ অভ্যাস নয় (কেবলমাত্র এই দুটি ধরণের সাথে ব্যবহার করে) - ইভেন্ট টিএসলিন্ট আপনাকে এটি করার অনুমতি দেবে। এটি কোনও কিছু সংজ্ঞায়িত হয়েছে কিনা তা যাচাই করা সহজ করে কারণ লেখার পরিবর্তে null !== someObject && undefined !== someObjectআপনি কেবল ব্যবহার করতে পারেনnull != someObject
— মেরেকি

14

ওপি-র প্রশ্নের সরাসরি উত্তর নয়, তবে আমার ক্ষেত্রে আমার নিম্নলিখিত সেটআপ ছিল -

ধরণ - v3.6.2
tslint -v5.20.0

এবং নিম্নলিখিত কোড ব্যবহার করে

const refToElement = useRef(null);

if (refToElement && refToElement.current) {
     refToElement.current.focus(); // Object is possibly 'null' (for refToElement.current)
}

আমি এই লাইনের জন্য সংকলকটি চেপে এগিয়ে চলেছি। নোট করুন যেহেতু এটি একটি সংকলক ত্রুটি এবং লিন্টারের ত্রুটি // tslint:disable-next-lineনয়, কাজ করে না। এছাড়াও, ডকুমেন্টেশন অনুসারে, এটি খুব কমই ব্যবহার করা উচিত, কেবল যখন প্রয়োজন হয় -

const refToElement = useRef(null);

if (refToElement && refToElement.current) {
     // @ts-ignore: Object is possibly 'null'.
     refToElement.current.focus(); 
}

আপডেট :

টাইপ করা বিষয় 3.7 সঙ্গে, আপনি ব্যবহার করতে পারেন ঐচ্ছিক chaining উপরের হিসাবে সমস্যা সমাধানের জন্য, -

refToElement?.current?.focus();

2
অক্ষম করার চেয়ে আরও ভাল সমাধান strictNullChecks, এর সাথে সতর্কতা অবলম্বন করা উচিত, বেশিরভাগ সময় আপনি নাল রেফারেন্স ত্রুটি চান কারণ এটি রাস্তায় আসল মাথা ব্যথা হতে পারে।
— অ্যান্ডি ব্রাহাম

'GetBoundingClientRect' সম্পত্তি 'কখনই নয়' টাইপটিতে বিদ্যমান নেই।
— মিকলিটি

আমার ক্ষেত্রে এই alচ্ছিক শৃঙ্খলা কাজ করে না। const input = useRef<HTMLInputElement>(null);এবং if (input && input.current) { input.current.value = ''; }কৌশলটি করেছে।
— টিমো

13

এই সমাধানটি আমার পক্ষে কাজ করেছে:

  • tsconfig.json এ যান এবং "سختনালচেকস" যুক্ত করুন: মিথ্যা

এখানে চিত্র বর্ণনা লিখুন


এটি আমার পক্ষেও কাজ করেছিল। যদিও এটি এখনও ত্রুটি প্রদানের মতো, যেমন সাবস্ক্রাইব বিবৃতিতে, ফলাফলের পরিবর্তনশীলকে স্বীকৃতি দিচ্ছে না, টাইপস্ক্রিপ্ট এটি ঘোষণা করতে চায়। সাবস্ক্রাইব (ফলাফল => this.result = ফলাফল.json ());
— আর্কি

আপনি কি 'ম্যাপ' অপারেটর ব্যবহার করার চেষ্টা করেছেন? গুগল 'আরএক্সজেএস / মানচিত্র'। আমি মূলত:। HTTP.get (...)। মানচিত্র (ফলাফল => ফলাফল.json ())। সাবস্ক্রাইব (ফলাফল => your আপনার জিনিস এখানে করুন})
— মহেশ নেপাল

38
প্রশ্নের উত্তর দেয় না। ওপি স্পষ্টভাবে বলেছিল: 'টিএস সংকলক চেকগুলি অক্ষম না করে'
— পিভিল

4
টাইপস্ক্রিপ্ট ব্যবহার করে এবং লটারে ত্রুটিটি সরিয়ে আপনি কী সতর্ক করতে চান? আমি মনে করি asআপনি যদি 100% নিশ্চিত হন তবে পছন্দসই মানটিই সর্বোত্তম বিকল্প । আমি MongoDB এবং FindOneOrUpdate ফেরত মান সঙ্গে কেস পেয়েছিলাম এবং আমি স্কিমা সামনে ছুঁড়ে দেওয়া কারণ ছিল result.valueহিসেবে ঘোষণা করা হয় TSchema | undefinedএবং আমি ইতিমধ্যে সঙ্গে চেক করেছি result.okআগে
— ভিনসেন্ট

12

আপনি যদি জানেন যে প্রকারটি কখনই হবে না nullবা undefined, আপনার foo: Barএটি এটির মতো প্রকাশ করা উচিত ?। ? Barসিনট্যাক্সের সাথে কোনও প্রকার ঘোষণার অর্থ এটি সম্ভাব্যরূপে সংজ্ঞায়িত হতে পারে যা আপনার জন্য যাচাই করা দরকার is

অন্য কথায়, সংকলক ঠিক আপনি যা করতে বলছেন তা করছে। আপনি যদি এটি alচ্ছিক হতে চান তবে আপনাকে পরে চেক করতে হবে।


1
"সংকলক আপনি যা বলছেন ঠিক তাই করছে" তাই আমার ধারণাটি ভুল, ধন্যবাদ। আমার কিছুটা অ্যাপ্রোচ বদলাতে হবে।
— গ্রাসনাল

আমার ক্ষেত্রে সংকলকটি সহজেই বুঝতে পারেনি যে আমি ইতিমধ্যে শূন্যের জন্য বস্তুটি পরীক্ষা করেছি। আমার কাছে একজন গিটার রয়েছে যা নাল পরীক্ষা করে পরীক্ষা করে get সুতরাং না, আমি যা জিজ্ঞাসা করেছি ঠিক এটি করছে না (এটি এই নয় যে আমি এটি সবকিছু আবিষ্কার করব বলে আশা করি না)।
— সিওয়াগনার

9

এটি ওপি-র সমস্যা নয়, তবে আমি একই Object is possibly 'null'বার্তাটি পেয়েছি যখন আমি দুর্ঘটনার কারণে পরামিতিটি নাল টাইপ হিসাবে ঘোষণা করেছি:

something: null;

এটি নাল মান নির্ধারণের পরিবর্তে:

something: string = null;

2
এটিই আসল উত্তর। হতাশাবোধ যখন আপনি প্রকৃত স্পষ্ট নাল চেক করেন এবং তবুও Object is possibly 'null'ত্রুটি পান। এই উত্তর যে সমাধান করে।
— বেন র্যাকিকোট

5

বিকল্প হিসাবে, আপনি টাইপ castালাই ব্যবহার করতে পারেন। টাইপসক্রিপ্ট থেকে যদি আপনার এই ত্রুটিটি থাকে তবে এর অর্থ হ'ল কিছু ভেরিয়েবলের টাইপ রয়েছে বা এটি সংজ্ঞায়িত:

let a: string[] | undefined;

let b: number = a.length; // [ts] Object is possibly 'undefined'
let c: number = (a as string[]).length; // ok

আপনার কোডটিতে aসত্যই উপস্থিত রয়েছে তা নিশ্চিত হন ।


3

টাইপস্ক্রিপ্ট ৩.7 ( https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html ) হিসাবে, আপনি এখন ?.কোনও অ্যাট্রিবিউট অ্যাক্সেস করার সময় অপারেটরটি অপরিজ্ঞাত করতে ব্যবহার করতে পারেন (বা কোনও পদ্ধতি কল করার পরে) ) নাল বা অপরিজ্ঞাত বস্তুর উপর:

inputEl?.current?.focus(); // skips the call when inputEl or inputEl.current is null or undefined

Propertyচ্ছিক সম্পত্তি অ্যাক্সেস অপারেটর ?.।
— অ্যাভেন্টুরিন

2

আরএক্সজেএস-এর জন্য টিপস

আমার প্রায়শই সদস্যের ভেরিয়েবল টাইপ Observable<string>হবে এবং আমি এটি শুরু করব না ngOnInit(অ্যাংুলার ব্যবহার করে)। সংকলকটি তখন এটি নির্বিঘ্নিত বলে ধরে নেয় কারণ এটি 'কনস্ট্রাক্টরে অবশ্যই নির্ধারিত নয়' - এবং সংকলকটি কখনই বুঝতে পারে না ngOnInit।

!ত্রুটি এড়াতে আপনি সংজ্ঞাটিতে সংজ্ঞা অপারেটরটি ব্যবহার করতে পারেন :

favoriteColor!: Observable<string>;

একটি অনিচ্ছাকৃত পর্যবেক্ষণযোগ্য 'আপনার অবশ্যই একটি স্ট্রিম সরবরাহ করতে হবে তবে আপনি নালাকে সরবরাহ করেছেন' এর মতো ত্রুটিযুক্ত সমস্ত ধরণের রানটাইম ব্যথার কারণ হতে পারে। !যদি আপনি জরিমানা স্পষ্টভাবে এটা ভালো কিছু সেট করা হতে যাচ্ছে জানি ngOnInit, কিন্তু ক্ষেত্রে যেখানে মান অন্য কোনও কম নির্ণায়ক ভাবে সেট করা হয় হতে পারে।

সুতরাং একটি বিকল্প আমি মাঝে মাঝে ব্যবহার করব:

public loaded$: Observable<boolean> = uninitialized('loaded');

যেখানে uninitializedকোথাও বিশ্বব্যাপী সংজ্ঞায়িত হয়েছে:

export const uninitialized = (name: string) => throwError(name + ' not initialized');

তারপরে আপনি যদি কখনও স্ট্রিমটিকে সংজ্ঞায়িত না করে ব্যবহার করেন এটি অবিলম্বে একটি রানটাইম ত্রুটি নিক্ষেপ করবে।


আমি সর্বত্র এটি করার পরামর্শ দিচ্ছি না, তবে আমি কখনও কখনও এটি করব - বিশেষত যদি বাইরে থেকে @ ইনপুট পরামিতিগুলির উপর নির্ভর করে থাকে
— সাইমন_উইভার

2

রিএকটিজেএস-তে, আমি ভেরিয়েবলগুলি শূন্য হয় কিনা তা কনস্ট্রাক্টরে যাচাই করি, যদি তারা হয় তবে আমি এটিকে ব্যতিক্রমের মতো আচরণ করি এবং ব্যতিক্রমটি যথাযথভাবে পরিচালনা করি। যদি ভেরিয়েবলগুলি শূন্য না হয়, কোড বহন করে এবং সংকলক সেই বিন্দুর পরে আর অভিযোগ করে না:

private variable1: any;
private variable2: any;

constructor(props: IProps) {
    super(props);

    // i.e. here I am trying to access an HTML element
    // which might be null if there is a typo in the name
    this.variable1 = document.querySelector('element1');
    this.variable2 = document.querySelector('element2');

    // check if objects are null
    if(!this.variable1 || !this.variable2) {
        // Manage the 'exception', show the user a message, etc.
    } else {
        // Interpreter should not complain from this point on
        // in any part of the file
        this.variable1.disabled = true; // i.e. this line should not show the error
    }

1

রাষ্ট্র স্থিতিকরণ এবং ব্যবহার করার সময় আমি প্রতিক্রিয়াটির সাথে এইটিতে ছুটে এসেছি map।

এই ক্ষেত্রে আমি একটি এপিআই আনার কল করছিলাম এবং প্রতিক্রিয়ার মান জানা যায় নি, তবে একটি "উত্তর" মান থাকা উচিত । আমি এর জন্য একটি কাস্টম প্রকার ব্যবহার করেছি, তবে মানটি nullহ'ল, যাইহোক, আমি টিএস ত্রুটি পেয়েছি। প্রকারটি nullএটিকে অনুমতি দেয় এটি ঠিক করে না; বিকল্পভাবে আপনি একটি ব্যবহার করতে পারেন default parameter value, তবে এটি আমার ক্ষেত্রে অগোছালো।

আমি কেবলমাত্র কোনও টার্নারি অপারেটর ব্যবহার করে প্রতিক্রিয়াটি ফাঁকা হওয়ার ইভেন্টে একটি ডিফল্ট মান সরবরাহ করে এটি অতিক্রম করেছি:

this.setState({ record: (response.Answer) ? response.Answer : [{ default: 'default' }] });

0

টাইপ স্ক্রিপ্টে আপনি দমন করতে নিম্নলিখিতগুলি করতে পারেন error:

let subString?: string;

subString > !null; - শূন্যের আগে যুক্ত বিস্মৃতি চিহ্নটি নোট করুন।


0

অবজেক্টকে এভাবে কল করার চেষ্টা করুন:

(<any>Object).dosomething

এই ত্রুটিটি এসেছে কারণ আপনি তাদের optionচ্ছিক ব্যবহার হিসাবে ঘোষণা করেছেন ?। এখন টাইপস্ক্রিপ্ট কঠোর চেক করে এবং এটি যা কিছু হতে দেয় তা অনুমতি দেবে না undefined। অতএব, আপনি (<any>yourObject)এখানে ব্যবহার করতে পারেন ।

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