টাইপস্ক্রিপ্টে পাবলিক স্ট্যাটিক কনস্ট


185

টাইপস্ক্রিপ্টে পাবলিক স্ট্যাটিক কনস্ট্যান্টসের মতো জিনিস কি আছে? আমার মতো একটি ক্লাস রয়েছে যা দেখতে:

export class Library {
  public static BOOK_SHELF_NONE: string = "None";
  public static BOOK_SHELF_FULL: string = "Full";
}

এই শ্রেণিতে, আমি করতে পারি Library.BOOK_SHELF_NONEএবং টিএসএস অভিযোগ করে না। তবে আমি যদি ক্লাস লাইব্রেরি অন্য কোথাও ব্যবহার করার চেষ্টা করি এবং একই জিনিস করার চেষ্টা করি তবে এটি এটি স্বীকৃতি দেয় না।


1
আপনি যে ক্লাসটি অন্য কোথাও ব্যবহার করার উদাহরণ দেখিয়ে দিতে পারেন?
— রায়না 77

@ raina77ow আমি কোডটি কীভাবে এটি ব্যবহার করব তা যুক্ত করতে শুরু করার সাথে সাথে আমি বুঝতে পেরেছিলাম যে এটি টিএসসি অভিযোগ করেছে যে নাম স্পেস করার কারণে। আপনি যদি এটি কোনও উত্তর হিসাবে রাখতে চান তবে আমি এটিকে সম্পূর্ণ হিসাবে চিহ্নিত করতে পারি যেহেতু আপনি আমাকে এটি খুঁজে পেতে সহায়তা করেছিলেন। আমি আমার নিজের প্রশ্নের উত্তর দিতে পছন্দ করি না।
— ক্রিস্টাল

আহ, কারণ ছিল। ) খুশি আমি সাহায্য করেছি; সংকলনের ফলাফল দেখিয়ে আমি উত্তর যুক্ত করব।
— raina77ow

1
আমি আরও readonlyনিশ্চিত করে যোগ করব যে টাইপস্ক্রিপ্ট আপনাকে সতর্ক করবে যদি আপনি কখনও সেসব ক্ষেত্রগুলি পুনরায় নিয়োগের চেষ্টা করেন:public static readonly BOOK_SHELF_FULL
— জান মোলাক

উত্তর:


26

এই টিএস স্নিপেট কী সংকলিত হয়েছে তা এখানে ( টিএস খেলার মাঠের মাধ্যমে ):

define(["require", "exports"], function(require, exports) {
    var Library = (function () {
        function Library() {
        }
        Library.BOOK_SHELF_NONE = "None";
        Library.BOOK_SHELF_FULL = "Full";
        return Library;
    })();
    exports.Library = Library;
});

আপনি দেখতে পাচ্ছেন, সংজ্ঞাযুক্ত উভয় সম্পত্তিই public staticকেবল রফতানি ফাংশনের সাথে সংযুক্ত থাকে (এর বৈশিষ্ট্য হিসাবে); অতএব আপনি যথাযথভাবে ফাংশনটি অ্যাক্সেস না করা পর্যন্ত এগুলি অ্যাক্সেসযোগ্য হওয়া উচিত।


428

আপনি যদি এমন কোনও কিছু চান যা আধুনিক ব্রাউজারগুলিতে স্থির ধ্রুবক মানের মতো আচরণ করে (এটি অন্য কোড দ্বারা পরিবর্তন করা যায় না) তবে আপনি শ্রেণিতে getএকমাত্র অ্যাক্সেসর যুক্ত করতে পারেন Library(এটি কেবল ES5 + ব্রাউজার এবং নোডজেএস এর জন্য কাজ করবে) :

export class Library {
    public static get BOOK_SHELF_NONE():string { return "None"; }
    public static get BOOK_SHELF_FULL():string { return "Full"; }   
}

var x = Library.BOOK_SHELF_NONE;
console.log(x);
Library.BOOK_SHELF_NONE = "Not Full";
x = Library.BOOK_SHELF_NONE;
console.log(x);

আপনি যদি এটি চালান, আপনি দেখবেন কীভাবে BOOK_SHELF_NONEসম্পত্তিটিকে একটি নতুন মান সেট করার প্রচেষ্টা কার্যকর হয় না।

2.0

টাইপস্ক্রিপ্ট ২.০ এ, আপনি readonlyখুব অনুরূপ ফলাফল অর্জন করতে ব্যবহার করতে পারেন :

export class Library {
    public static readonly BOOK_SHELF_NONE = "None";
    public static readonly BOOK_SHELF_FULL = "Full";
}

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


26
এই যেমন একটি ভাল উত্তর। আমার কোডিং এর কারণে এখন আরও সুখী।
— gonzofish

7
যদিও এই সমাধানটির একটি অসুবিধা রয়েছে - আপনি এই গতিশীল মানগুলি টাইপ সীমাবদ্ধতা হিসাবে ব্যবহার করতে পারবেন না , উদাহরণস্বরূপ:type MyType: Library.BOOK_SHELF_NONE | Library.BOOK_SHELF_FULL;
— কোস্টিয়্যান্টিন কোলেসনিকেনকো

2
@ অ্যাড্রিয়ানমাইসা - দয়া করে একটি নতুন প্রশ্ন জিজ্ঞাসা করুন।
— তারযুক্তপ্রেইরি

2
@ হেক্স-দয়া করে একটি নতুন প্রশ্ন জিজ্ঞাসা করুন।
— তারযুক্তপ্রেই

1
Enums সম্পর্কে কি?
— কৌতূহলী 95

40

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

export namespace Library {
    export const BOOK_SHELF_NONE: string = 'NONE';
}

তারপরে আপনি এটিকে অন্য যে কোনও জায়গা থেকে আমদানি করতে পারবেন:

import {Library} from './Library';
console.log(Library.BOOK_SHELF_NONE);

আপনার যদি সেখানে কোনও ক্লাসের প্রয়োজন হয় তবে পাশাপাশি নামের জায়গার ভিতরে এটি অন্তর্ভুক্ত করুন: export class Book {...}


2
যদি আমি কোনও বস্তুর প্রারম্ভিককরণে ধ্রুবকগুলি ব্যবহার করি তবে তারা স্বীকৃত বলে মনে হয় না। উদাহরণস্বরূপ: { type: Library.BOOK_SHELF_NONE }মনে হয় যে নামের স্থানটির কোনও রফতানি কল নেই BOOK_SHELF_NONE। যাইহোক, আমি যদি কেবলমাত্র স্থানীয় রেফারেন্সটি রেফারেন্স সহ সেট করে থাকি তবে এটি সূক্ষ্মভাবে সমাধান করে। টিএস 2.2
— ক্রাশ

13

এদিকে এটি ডেকরেটারের সাথে সমাধান করা যেতে পারে Object.freezeবা এর সাথে একত্রে Object.defineProperty, আমি এটি ব্যবহার করছি, এটি টন গেটার ব্যবহারের চেয়ে খানিকটা সুন্দর। আপনি এটি সরাসরি টিএস প্লেগ্রাউন্ডটিকে কার্যত দেখতে কপি / পেস্ট করতে পারেন। - দুটি বিকল্প আছে


স্বতন্ত্র ক্ষেত্রগুলিকে "চূড়ান্ত" করুন

নীচের সাজসজ্জাটি বিশৃঙ্খল স্থিতিশীল এবং অ-স্থির ক্ষেত্র উভয়কে "গিটার-কেবল-বৈশিষ্ট্যগুলিতে" রূপান্তর করে।

দ্রষ্টব্য : যদি কোনও প্রাথমিক মানবিহীন কোনও উদাহরণ-পরিবর্তনশীল টীকাযুক্ত করা হয় @final, তবে প্রথম নির্ধারিত মান (কখনই নয়) চূড়ান্ত হবে।

// example
class MyClass {
    @final
    public finalProp: string = "You shall not change me!";

    @final
    public static FINAL_FIELD: number = 75;

    public static NON_FINAL: string = "I am not final."
}

var myInstance: MyClass = new MyClass();
myInstance.finalProp = "Was I changed?";
MyClass.FINAL_FIELD = 123;
MyClass.NON_FINAL = "I was changed.";

console.log(myInstance.finalProp);  // => You shall not change me!
console.log(MyClass.FINAL_FIELD);   // => 75
console.log(MyClass.NON_FINAL);     // => I was changed.

সাজসজ্জা: নিশ্চিত করুন যে আপনি এটি আপনার কোডে অন্তর্ভুক্ত করেছেন!

/**
* Turns static and non-static fields into getter-only, and therefor renders them "final".
* To use simply annotate the static or non-static field with: @final
*/
function final(target: any, propertyKey: string) {
    const value: any = target[propertyKey];
    // if it currently has no value, then wait for the first setter-call
    // usually the case with non-static fields
    if (!value) {
        Object.defineProperty(target, propertyKey, {
            set: function (value: any) {
                Object.defineProperty(this, propertyKey, {
                    get: function () {
                        return value;
                    },
                    enumerable: true,
                    configurable: false
                });
            },
            enumerable: true,
            configurable: true
        });
    } else { // else, set it immediatly
        Object.defineProperty(target, propertyKey, {
            get: function () {
                return value;
            },
            enumerable: true
        });
    }
}

উপরের সাজসজ্জার বিকল্প হিসাবে, এর একটি কঠোর সংস্করণও থাকবে, যা কেউ "use strict";সেট হওয়ার সাথে ক্ষেত্রটির জন্য কিছু মান নির্ধারণ করার চেষ্টা করলে এমন একটি ত্রুটি এমনকি ছুঁড়ে ফেলবে । (যদিও এটি কেবল স্থির অংশ)

/**
 * Turns static fields into getter-only, and therefor renders them "final".
 * Also throws an error in strict mode if the value is tried to be touched.
 * To use simply annotate the static field with: @strictFinal
 */
function strictFinal(target: any, propertyKey: string) {
    Object.defineProperty(target, propertyKey, {
        value: target[propertyKey],
        writable: false,
        enumerable: true
    });
}

প্রতিটি স্থির ক্ষেত্রকে "চূড়ান্ত" করুন

সম্ভাব্য ডাউনসাইড: এটি কেবল সেই শ্রেণীর সমস্ত স্ট্যাটিক্সের জন্য বা কোনওটির জন্যই কাজ করবে না, তবে নির্দিষ্ট স্ট্যাটিকগুলিতে প্রয়োগ করা যাবে না।

/**
* Freezes the annotated class, making every static 'final'.
* Usage:
* @StaticsFinal
* class MyClass {
*      public static SOME_STATIC: string = "SOME_STATIC";
*      //...
* }
*/
function StaticsFinal(target: any) {
    Object.freeze(target);
}
// Usage here
@StaticsFinal
class FreezeMe {
    public static FROZEN_STATIC: string = "I am frozen";
}

class EditMyStuff {
    public static NON_FROZEN_STATIC: string = "I am frozen";
}

// Test here
FreezeMe.FROZEN_STATIC = "I am not frozen.";
EditMyStuff.NON_FROZEN_STATIC = "I am not frozen.";

console.log(FreezeMe.FROZEN_STATIC); // => "I am frozen."
console.log(EditMyStuff.NON_FROZEN_STATIC); // => "I am not frozen."

আমি মনে করি এটিই সবচেয়ে পরিষ্কার পদ্ধতি। ধন্যবাদ!
— থিবস

একটি ছোট সংযোজন: স্থির মান হতে দেওয়া if (!value)উচিত বা । if (value === undefined)""0
— লিওন অ্যাডলার

6

ধন্যবাদ ওয়্যার্ডপ্রাইরি!

আপনার উত্তরটি কিছুটা প্রসারিত করার জন্য, এখানে ধ্রুবক শ্রেণীর সংজ্ঞা দেওয়ার সম্পূর্ণ উদাহরণ।

// CYConstants.ts

class CYConstants {
    public static get NOT_FOUND(): number    { return -1; }
    public static get EMPTY_STRING(): string { return ""; }
}

export = CYConstants;

ব্যবহার করা

// main.ts

import CYConstants = require("./CYConstants");

console.log(CYConstants.NOT_FOUND);    // Prints -1
console.log(CYConstants.EMPTY_STRING); // Prints "" (Nothing!)

2

নিম্নলিখিত সমাধানটি টিএস 1.7.5 হিসাবেও কাজ করে।

// Constancts.ts    
export const kNotFoundInArray = -1;
export const AppConnectionError = new Error("The application was unable to connect!");
export const ReallySafeExtensions = ["exe", "virus", "1337h4x"];

ব্যবহার করা:

// Main.ts    
import {ReallySafeExtensions, kNotFoundInArray} from "./Constants";

if (ReallySafeExtensions.indexOf("png") === kNotFoundInArray) {
    console.log("PNG's are really unsafe!!!");
}

এটি সত্যিই দুর্দান্ত, তবে আপনি যদি এটি কয়েকটি মান (যেমন আপনি অন্য ভাষায় এনামের মতো করতে পারেন) এর চেয়ে বেশি সংজ্ঞায়িত করতে ব্যবহার করেন তবে আপনি সমস্ত মান পৃথকভাবে আমদানি করতে আটকে গেছেন। এটি সত্যিই জটিল হয়ে উঠতে পারে!
— কোরি লারসন

100% সম্মত। এগুলির নাম স্থান দিতে সক্ষম হতে পারে তবে আমি এটিতে সন্ধান করিনি। হতে পারে আপনি "./Constants.ts" থেকে "অ্যারেকন্সট্যান্টস" আমদানি করতে পারেন এবং তারপরে অ্যারেসিস্ট্যান্টস.নোটফাউন্ডের মতো কিছু করতে পারেন। আমি সময় পেলে এর সাথে আরও খেলতে হবে।
— অ্যান্ড্রু

হ্যাঁ, আপনি পৃথকভাবে মানগুলি এড়াতে নেমস্পেস ব্যবহার করতে পারেন, আমার নিজের উত্তরটি এখানে পড়ুন।
— ইভান ক্যাসেলেলানোস

0

আপনার ক্লাসে কেবল 'এক্সপোর্ট' পরিবর্তনশীল এবং 'আমদানি' করুন

export var GOOGLE_API_URL = 'https://www.googleapis.com/admin/directory/v1';

// default err string message
export var errStringMsg = 'Something went wrong';

এখন এটি হিসাবে ব্যবহার করুন

import appConstants = require('../core/AppSettings');
console.log(appConstants.errStringMsg);
console.log(appConstants.GOOGLE_API_URL);

0

আপনি কোনও গেটর ব্যবহার করতে পারেন, যাতে আপনার সম্পত্তিটি কেবল পঠনযোগ্য হয়। উদাহরণ:

export class MyClass {
    private _LEVELS = {
        level1: "level1",
        level2: "level2",
        level2: "level2"
    };

    public get STATUSES() {
        return this._LEVELS;
    }
}

অন্য শ্রেণিতে ব্যবহৃত:

import { MyClass } from "myclasspath";
class AnotherClass {
    private myClass = new MyClass();

    tryLevel() {
       console.log(this.myClass.STATUSES.level1);
    }
}

এটি যা স্থির লিখনযোগ্য হবে বলে আশা করা হয়:let a = new MyClass(); a.STATUSES.level1 = 'not level1'; let plainWrong = new MyClass().STATUSES.level1; // 'not level1'
— লিওন অ্যাডলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.