টাইপস্ক্রিপ্ট - সেটটাইমআউট (নোড বনাম উইন্ডো) এর সঠিক সংস্করণ ব্যবহার করুন


129

আমি সর্বশেষতম সংকলক সংস্করণটি ব্যবহার করতে কিছু পুরানো টাইপস্ক্রিপ্ট কোড আপগ্রেড করার কাজ করছি, এবং কল করতে আমার সমস্যা হচ্ছে setTimeout। কোডটি ব্রাউজারের ফাংশনটিতে কল করার প্রত্যাশা setTimeoutকরে যা একটি নম্বর দেয়:

setTimeout(handler: (...args: any[]) => void, timeout: number): number;

যাইহোক, সংকলকটি নোড প্রয়োগের পরিবর্তে এর সমাধান করছে, যা কোনও নোডজেএস.আবারকে রিটার্ন দেয়:

setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;

এই কোডটি নোডে চলবে না, তবে নোডের টাইপগুলি অন্য কোনও কিছুর উপর নির্ভরশীলতা হিসাবে টানা হচ্ছে (কী তা নিশ্চিত নয়)।

আমার setTimeoutযে সংস্করণটি চান সেটি বেছে নিতে আমি কীভাবে সংকলককে নির্দেশ দিতে পারি?

এখানে প্রশ্নে কোডটি রয়েছে:

let n: number;
n = setTimeout(function () { /* snip */  }, 500);

এটি সংকলক ত্রুটি উত্পাদন করে:

TS2322: টাইম 'টাইমার' টাইপ 'নম্বর' টাইপ করার যোগ্য নয়।


আপনার tsconfig.json- তে কি কোনও প্রকার রয়েছে: ["নোড"]? দেখুন stackoverflow.com/questions/42940954/...
derkoe

@ কো না, আমার কাছে টাইপগুলি নেই: ["নোড"] টিএসকনফিগ ফাইলে বিকল্প। তবে নোডের ধরণগুলি অন্য কোনও কিছুতে এনপিএম নির্ভরতা হিসাবে টানছে।
কেভিন টিঘে

4
Tsconfig.json- এ আপনি স্পষ্টভাবে "প্রকারগুলি" সংজ্ঞায়িত করতে পারেন - আপনি যখন "নোড" বাদ দেন তখন এটি সংকলনে ব্যবহৃত হয় না। যেমন "প্রকার": ["jQuery"]
derkoe

4
অবাক করার মতো বিষয় যে @Koe- এর উত্তর ("প্রকারের" বিকল্পের) কোনও ভোট নেই, একমাত্র সত্য সঠিক উত্তর।
ডিম নেপোমন্যাসচিহ

@ কেভিনটিঘে এর typesঅন্তর্ভুক্ত নেই nodeতবে setTimeoutতার ব্রাউজারের চেয়ে তার নোড টাইপ পাওয়া যায়। typesসমস্ত ধরনের ডিফল্ট node_modules/@types, ব্যাখ্যা যেমন typescriptlang.org/tsconfig#types কিন্তু এমনকি আপনি যদি না উল্লেখ typesএবং না অন্তর্ভুক্ত "node", কেন নেই setTimeoutএখনো তার নোড ধরনের পাওয়া এবং কিভাবে আপনি ব্রাউজারের ধরন পেতে পারেন? @ আজকের সমাধানটি হ্যাকের সামান্য বিষয়, মূলত এটি যা ফিরে আসে তা ফিরিয়ে দেয়। টাইপসক্রিপ্টটি এখনও ভুল ধরণের সন্ধান করতে পারে তবে কমপক্ষে এটি নিয়মিত ভুল হবে।
ডেনিস হাউ

উত্তর:


101

ভেরিয়েবল ঘোষণাকে প্রভাবিত করে না এমন আরও একটি কাজের:

let n: number;
n = <any>setTimeout(function () { /* snip */  }, 500);

এছাড়াও, windowঅবজেক্টটি স্পষ্টভাবে ব্যবহার করা সম্ভব any:

let n: number;
n = window.setTimeout(function () { /* snip */  }, 500);

26
আমি মনে করি অন্য একটি ( window.setTimeout) এই প্রশ্নের সঠিক উত্তর হওয়া উচিত কারণ এটি পরিষ্কার সমাধান।
amik

4
আপনি যদি anyপ্রকারটি ব্যবহার করে থাকেন তবে আপনি সত্যিই কোনও টাইপস্ক্রিপ্ট উত্তর দিচ্ছেন না।
এস ..

অনুরূপভাবে numberটাইপটি স্ক্রিপ্টের নির্দিষ্ট লিঙ্ক ত্রুটির দিকে পরিচালিত করবে, কারণ এতে setTimeoutফাংশনের চেয়ে বেশি প্রয়োজন।
এস ..

4
window.setTimeoutইউনিট পরীক্ষা ফ্রেমওয়ার্ক (নোড.জেএস) নিয়ে সমস্যা সৃষ্টি করতে পারে। সবচেয়ে ভাল সমাধান ব্যবহার let n: NodeJS.Timeoutএবং n = setTimeout
চেম্বারলাইন

128
let timer: ReturnType<typeof setTimeout> = setTimeout(() => { ... });

clearTimeout(timer);

ব্যবহার করে ReturnType<fn>আপনি প্ল্যাটফর্ম থেকে স্বাধীনতা পাচ্ছেন। আপনি ব্যবহার করতে বাধ্য করা হবে না anyকিংবা window.setTimeoutযা হবে যদি আপনি কোড কোন nodeJS সার্ভার (যেমন। সার্ভার সাইড অনুষ্ঠিত পৃষ্ঠা) চালানো বিরতি।


সুসংবাদ, এটিও ডেনোর সাথে সামঞ্জস্যপূর্ণ!


10
আমার বোঝার যে এই সঠিক উত্তর এবং গৃহীত একটি হতে হবে, যেহেতু এটি যে প্ল্যাটফর্ম সমর্থনের জন্য সঠিক প্রকারের সংজ্ঞা প্রদান করে setTimeout/ clearTimeoutএবং ব্যবহার করে না any
আফেন্সার

12
আপনি যদি কোনও লাইব্রেরি লিখতে থাকেন যা নোডজেএস এবং ব্রাউজার উভয় ক্ষেত্রেই চালিত হয় তবে এটিই সমাধান।
ইয়াকিলিম

4
রিটার্ন টাইপ হয় NodeJS.Timeoutযদি ব্যবহার setTimeoutসরাসরি এবং numberযদি ব্যবহার window.setTimeout। ব্যবহার করার দরকার নেই ReturnType
চেম্বারলাইন

@ চ্যাচম্বরলাইন আপনি setTimeoutফাংশনটি চালানোর সময় আপনার এটির প্রয়োজন হবে এবং তার ফলটি ভেরিয়েবলের মধ্যে সংরক্ষণের আশা করছেন। টিএস খেলার মাঠে এটি নিজে চেষ্টা করুন।
আক্সে

ওপি এবং আমার ক্ষেত্রে, টাইপস্ক্রিপ্টটি setTimeoutভুলের ধরণটি পায় (কারণগুলির কারণে কেউ ব্যাখ্যা করতে পারে না) তবে কমপক্ষে এই সমাধানটি মাস্ক করা উচিত যা কেবল ব্যবহারের চেয়ে কিছুটা আরও ভাল উপায়ে করা উচিত any
ডেনিস হাউ

15

আমি অনুমান করি যে এটি আপনার কোডটি কোথায় চালাবেন তার উপর নির্ভর করে।

যদি আপনার রানটাইম টার্গেটটি সার্ভার সাইড নোড জেএস হয় তবে ব্যবহার করুন:

let timeout: NodeJS.Timeout;
global.clearTimeout(timeout);

আপনার রানটাইম টার্গেট যদি ব্রাউজার হয় তবে ব্যবহার করুন:

let timeout: number;
window.clearTimeout(timeout);

6

এটি সম্ভবত পুরানো সংস্করণগুলির সাথে কাজ করবে তবে টাইপস্ক্রিপ্ট সংস্করণ ^3.5.3এবং নোড.জেএস সংস্করণ সহ ^10.15.3আপনার টাইমার মডিউল থেকে নোড-নির্দিষ্ট ফাংশনগুলি আমদানি করতে সক্ষম হওয়া উচিত :

import { setTimeout } from 'timers';

এটি টাইমআউট টাইপের টাইমের একটি উদাহরণ প্রদান করবে NodeJS.Timeoutযা আপনি এখানে পাঠাতে পারেন clearTimeout:

import { clearTimeout, setTimeout } from 'timers';

const timeout: NodeJS.Timeout = setTimeout(function () { /* snip */  }, 500);

clearTimeout(timeout);

4
একইভাবে, আপনি যদি ব্রাউজারের সংস্করণ চান তবে এর setTimeoutমতো কিছু const { setTimeout } = windowএই ত্রুটিগুলি পরিষ্কার করে দেবে।
জ্যাক স্টিম

2

আমি একই সমস্যার মুখোমুখি হয়েছিলাম এবং আমাদের দলটি যে টিউমারটি ব্যবহারের সিদ্ধান্ত নিয়েছে, তা কেবল টাইমার টাইপের জন্য "কোনও" ব্যবহার করা ছিল। যেমন:

let n: any;
n = setTimeout(function () { /* snip */  }, 500);

এটি সেটটাইমআউট / সেটইন্টারওয়াল / ক্লিয়ারটাইমআউট / ক্লিয়ারআইন্টারভাল পদ্ধতি উভয় বাস্তবায়নের সাথে কাজ করবে।


4
হ্যাঁ, এটা কাজ করে। আমি আরও বুঝতে পারি যে আমি কেবল উইন্ডো অবজেক্টে পদ্ধতিটি নির্দিষ্ট করতে পারি: উইন্ডো.সেটটাইমআউট (...)। এটি যাওয়ার সবচেয়ে ভাল উপায় কিনা তা নিশ্চিত নই তবে আমি আপাতত এটি দিয়েই থাকব।
কেভিন টিঘে

4
আপনি টাইপ স্ক্রিপ্টে নোডজেএস নেমস্পেসটি সঠিকভাবে আমদানি করতে পারেন, এই উত্তরটি দেখুন
hlovdal

প্রকৃতপক্ষে প্রশ্নের উত্তর দেওয়ার জন্য ("আমি যে সংস্করণটি চাই তার চয়ন করতে আমি কীভাবে সংকলককে নির্দেশ দিতে পারি"), আপনি তার পরিবর্তে উইন্ডো.সেটটাইমআউট () ব্যবহার করতে পারেন, যেমন @ নীচে উত্তর দিয়েছেন as
আনসন ভ্যানডোরেন

window.setTimeoutইউনিট পরীক্ষা ফ্রেমওয়ার্কের সাথে কাজ নাও করতে পারে। এখানে একটি ধরণের ব্যবহার করা যেতে পারে .. এটির NodeJS.Timeout। আপনি ভাবতে পারেন আপনি নোডের পরিবেশে নেই তবে আমার কাছে আপনার জন্য একটি সংবাদ আছে: ওয়েবপ্যাক / টাইপসক্রিপ্ট ইত্যাদি নোড.জেএস চালাচ্ছে।
চেম্বারলাইন

0
  • আপনি যদি টাইমার সম্পর্কিত টাইপ স্ক্রিপ্টের জন্য এখানে সমাধান চান তবে আমরা যাব:

    বাগটি 'নম্বর' রিটার্নে টাইপ হয় এটি টাইমার বা অন্য কিছু নয়।

    এটি টাইপ স্ক্রিপ্ট সংস্করণ ~> 2.7 সমাধানের জন্য:

export type Tick = null | number | NodeJS.Timer;

এখন আমরা সব ঠিক করেছি, ঠিক এইরকম ঘোষণা করুন:

 import { Tick } from "../../globals/types";

 export enum TIMER {
    INTERVAL = "INTERVAL",
    TIMEOUT = "TIMEOUT", 
 };

 interface TimerStateI {
   timeInterval: number;
 }

 interface TimerI: TimerStateI {
   type: string;
   autoStart: boolean;
   isStarted () : bool;
 }

     class myTimer extends React.Component<TimerI, TimerStateI > {

          private myTimer: Tick = null;
          private myType: string = TIMER.INTERVAL;
          private started: boll = false;

          constructor(args){
             super(args);
             this.setState({timeInterval: args.timeInterval});

             if (args.autoStart === true){
               this.startTimer();
             }
          }

          private myTick = () => {
            console.log("Tick");
          }    

          private startTimer = () => {

            if (this.myType === TIMER.INTERVAL) {
              this.myTimer = setInterval(this.myTick, this.timeInterval);
              this.started = true;
            } else if (this.myType === TIMER.TIMEOUT) {
              this.myTimer = setTimeout(this.myTick, this.timeInterval);
              this.started = true;
            }

          }

         private isStarted () : bool {
           return this.started;
         }

     ...
     }

0

আপনি লক্ষ্য করে থাকেন তবে setIntervalএর window। তাহলে আপনি এটি হিসাবে লিখতে পারেন

let timerId: number = setInterval((()=>{
    this.populateGrid(true)
  }) as TimerHandler, 5*1000)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.