টাইপস্ক্রিপ্ট ইন্টারফেসে স্থির সম্পত্তি কীভাবে সংজ্ঞায়িত করা যায়


122

আমি শুধু টাইপস্ক্রিপ্ট ইন্টারফেসে একটি স্থির সম্পত্তি ঘোষণা করতে চান ? আমি এই সম্পর্কে কোথাও খুঁজে পাই না।

interface myInterface {
  static Name:string;
}

এটা কি সম্ভব?


আপনি ঠিক কী মডেল করার চেষ্টা করছেন?
— রায়ান কাভানফ

5
'ক্লাস ফু প্রয়োগকারী বার' ব্যবহারের কথা বিবেচনা করুন যেখানে বারটিও একটি শ্রেণি। আপনি টিএস এর অন্যান্য ক্লাস দ্বারা ক্লাস 'প্রয়োগ' করতে পারেন।
— টোবিয়াস চুদনিক

উত্তর:


46

আপনি টাইপস্ক্রিপ্টে একটি ইন্টারফেসে একটি স্ট্যাটিক সম্পত্তি নির্ধারণ করতে পারবেন না।

বলুন যে আপনি Dateসংজ্ঞায়িত সংজ্ঞা যুক্ত করার পরিবর্তে অবজেক্টটি পরিবর্তন করতে চেয়েছিলেন Date, আপনি এটিকে মোড়ানো করতে পারেন বা না করে এমন জিনিসগুলি করার জন্য কেবল আপনার সমৃদ্ধ তারিখ শ্রেণি তৈরি Dateকরতে পারেন।

class RichDate {
    public static MinValue = new Date();
}

যেহেতু তারিখ টাইপস্ক্রিপ্টের একটি ইন্টারফেস, তাই আপনি extendsকীওয়ার্ডটি ব্যবহার করে এটি কোনও শ্রেণীর সাথে বাড়িয়ে দিতে পারবেন না , যা লজ্জার বিষয় কারণ তারিখটি কোনও শ্রেণি হলে এটি একটি ভাল সমাধান হত।

MinValueপ্রোটোটাইপে কোনও সম্পত্তি সরবরাহের জন্য আপনি যদি তারিখ অবজেক্টটি প্রসারিত করতে চান তবে আপনি এটি করতে পারেন:

interface Date {
    MinValue: Date;
}

Date.prototype.MinValue = new Date(0);

ব্যবহার করে কল করা:

var x = new Date();
console.log(x.MinValue);

এবং যদি আপনি এটি কোনও উদাহরণ ছাড়াই উপলব্ধ করতে চান তবে আপনি এটিও করতে পারেন ... তবে এটি কিছুটা উদ্বেগজনক।

interface DateStatic extends Date {
    MinValue: Date;
}

Date['MinValue'] = new Date(0);

ব্যবহার করে কল করা:

var x: DateStatic = <any>Date; // We aren't using an instance
console.log(x.MinValue);

1
@ রাজাগোপাল পরিষ্কার হতে, আপনি extendsকীওয়ার্ডটি ব্যবহার করে টিএস-তে ইন্টারফেসগুলি প্রসারণ করতে পারবেন । আপনি কেবল কোনও শ্রেণীর সাথে একটি ইন্টারফেস প্রসারিত করতে পারবেন না (একটি স্ট্যাটিক সম্পত্তি যুক্ত করার জন্য আপনাকে যা করতে হবে)।
— জুড ফিশার

স্টিভ - 'যেহেতু তারিখ টাইপস্ক্রিপ্টের একটি ইন্টারফেস, আপনি এক্সটেন্ডস কীওয়ার্ড ব্যবহার করে এটি বাড়িয়ে দিতে পারবেন না' - এটি ঠিক নয়, তাই না?
— জুড ফিশার

1
আপনি ইন্টারফেসটি প্রসারিত করতে পারেন, তবে আপনি এটি কোনও শ্রেণীর সাথে প্রসারিত করতে পারবেন না, কেবল এটি বাস্তবায়ন করুন। আমি এটা পরিষ্কার করিনি।
— ফেনটন

আমি নিকোসের মতামতকে দ্বিতীয় করব। ইন্টারফেসের উত্তরাধিকার পঠনযোগ্যতা বৃদ্ধির উদ্দেশ্যে পরাস্ত করে না তাই রক্ষণশীলতা হ্রাস করে? এমন কি এমন কেউ আছেন যে কোনও নতুনের পরিবর্তে ইন্টারফেসের উত্তরাধিকার কেন ব্যবহার করবেন সে সম্পর্কে যৌক্তিক ধারণা দিতে পারেন?
— টমাস হেসে

@ টমাসহিস that (প্রথম) প্রশ্নের একক সঠিক উত্তর নেই। এই সিদ্ধান্তগুলি প্রতিদ্বন্দ্বী দাবির মধ্যে বাণিজ্য-অফ এবং সঠিক উত্তরটি উপযুক্ত প্রসঙ্গে ট্রেড-অফকে মূল্যায়ন করা।
— ফেন্টন

98

বছর কেটে যাওয়ার পরে একটি কার্যকর উপায় সরবরাহ করতে এখানে ডানকের @ বার্টভিডস এর উত্তর অনুসরণ করুন।

এই মুহুর্তে টাইপসক্রিপ্ট 1.5 প্রকাশের পরে (@ জুন 15 '15), আপনার সহায়ক ইন্টারফেস

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

সাজসজ্জার সাহায্যে এভাবে বাস্তবায়ন করা যেতে পারে।

/* class decorator */
function staticImplements<T>() {
    return <U extends T>(constructor: U) => {constructor};
}

@staticImplements<MyTypeStatic>()   /* this statement implements both normal interface & static interface */
class MyTypeClass { /* implements MyType { */ /* so this become optional not required */
    public static staticMethod() {}
    instanceMethod() {}
}

গিথুব ওপেন ইস্যুতে আমার মন্তব্যটি দেখুন 13462 ।

ভিজ্যুয়াল ফলাফল: স্থির পদ্ধতি অনুপস্থিত একটি ইঙ্গিত সহ ত্রুটি সংকলন। এখানে চিত্র বর্ণনা লিখুন

স্থির পদ্ধতি প্রয়োগের পরে, পদ্ধতি অনুপস্থিত হওয়ার ইঙ্গিত। এখানে চিত্র বর্ণনা লিখুন

স্থির ইন্টারফেস এবং সাধারণ ইন্টারফেস উভয়ই পূরণের পরে সংকলনটি কেটে গেল। এখানে চিত্র বর্ণনা লিখুন


5
আপনার উত্তর উত্তর। তোমাকে অনেক ধন্যবাদ. টাইপস্ক্রিপ্ট 2.4.1 এর সাথে কাজ করা
— জুয়ান ক্যামিলো গুয়ারিন পি

এই উত্তরটি আমার জন্য টাইপস্ক্রিপ্ট 3.0.1
— মিমিফেফ

2
@ মিম্মেফ আমি 3.0.1 দিয়ে পরীক্ষা করেছি এবং এটি কাজ করে। "কাজ না করা" মানে কি? কোন ত্রুটি বার্তা আছে?
— Val,

1
@ চেকলাং ধন্যবাদ! আমি আপনার পরামর্শের সঙ্গে আমার উত্তর আপডেট
— Val,

1
একটি বিমূর্ত শ্রেণীর সাহায্যে আমরা এটি কীভাবে করতে পারি?
— জিওইউজ

16

আপনি সাধারণত ইন্টারফেস সংজ্ঞায়িত করতে পারেন:

interface MyInterface {
    Name:string;
}

তবে আপনি ঠিক করতে পারবেন না

class MyClass implements MyInterface {
    static Name:string; // typescript won't care about this field
    Name:string;         // and demand this one instead
}

স্থিতিশীল বৈশিষ্ট্যের জন্য কোনও শ্রেণীর এই ইন্টারফেসটি অনুসরণ করা উচিত তা প্রকাশ করার জন্য আপনার কিছুটা কৌশল প্রয়োজন:

var MyClass: MyInterface;
MyClass = class {
    static Name:string; // if the class doesn't have that field it won't compile
}

আপনি এমনকি শ্রেণীর নাম রাখতে পারেন, টাইপস্ক্রিপ্ট (২.০) কিছু মনে করবে না:

var MyClass: MyInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that field it won't compile
}

আপনি যদি অনেকগুলি ইন্টারফেস থেকে স্থিতিশীলভাবে উত্তরাধিকার পেতে চান তবে আপনাকে সেগুলিকে প্রথমে একটি নতুনতে মিশতে হবে:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
interface NameAndAddressInterface extends NameInterface, AddressInterface { }
var MyClass: NameAndAddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

অথবা আপনি যদি মার্জড ইন্টারফেসটির নাম রাখতে না চান তবে আপনি এটি করতে পারেন:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
var MyClass: NameInterface & AddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

কাজের উদাহরণ


আমি ত্রুটি পেয়েছি টিএস 2322: বেনাম শ্রেণি টাইপ করার
— যোগ্য

@ ফায়ারকোডিং আপনি কোন টাইপস্ক্রিপ্ট সংস্করণটি ব্যবহার করছেন? আমার উদাহরণগুলি 2.0
— কামিল জাজোট

এটি কাস্টম সজ্জাকারীর চেয়ে আরও সহজ সমাধান @staticImplements।
— রবার্ট পেনার

1
আমি মনে করি এটি একটি দুর্দান্ত সমাধান। reply(msg: IBotMsg): Promise<IBotReply>
— অ্যাসিঙ্ক

স্থির এবং উদাহরণ উভয় পদ্ধতিরই সংজ্ঞা দেওয়ার কোনও উপায় আছে বা সমস্ত পদ্ধতি এখন কেবল স্থির?
— dcsan

15

স্থির বৈশিষ্ট্যগুলি সাধারণত (বৈশ্বিক) অবজেক্টের জন্য কনস্ট্রাক্টরের উপর স্থাপন করা হয়, যেখানে "ইন্টারফেস" কীওয়ার্ডটি বস্তুর উদাহরণগুলিতে প্রযোজ্য।

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

declare var myInterface : {
  new(): Interface;
  Name:string;
}

সম্পাদনা করুন: নীচে
— বার্টভিডস

টাইপসক্রিপ্ট 1.5 প্রকাশের পরে এই মুহুর্তে (6.15.2015), এখানে কোনও শ্রেণীর স্থির সদস্যদের বর্ণনা করার একটি কার্যক্ষম উপায়। stackoverflow.com/a/43674389/681830
— Val,

8

স্ট্যাটিক সংশোধকগুলি কোনও প্রকার সদস্যের উপরে উপস্থিত হতে পারে না (টাইপস্ক্রিপ্ট ত্রুটি টিএস 1070) এজন্য আমি মিশনটি সমাধান করতে একটি বিমূর্ত ক্লাস ব্যবহার করার পরামর্শ দিচ্ছি:

উদাহরণ

// Interface definition
abstract class MyInterface {
  static MyName: string;
  abstract getText(): string;
}

// Interface implementation
class MyClass extends MyInterface {
  static MyName = 'TestName';
  getText(): string {
    return `This is my name static name "${MyClass.MyName}".`;
  }
}

// Test run
const test: MyInterface = new MyClass();
console.log(test.getText());

হ্যাঁ, এই উত্তর!
— vintproykt

7

new()স্ট্যাটিক ধরণের জন্য নির্দিষ্ট করে উপরে ডানকানের সমাধানটি ইন্টারফেসের সাথেও কাজ করে:

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

এর মধ্যে কোনটি আমার ক্লাস হবে implement?
— ডেনিস সেশেনভ

2
এই মুহুর্তে আপনি স্থায়ী সদস্যদের, উদাহরণস্বরূপ সদস্যদের বর্ণনা করতে কোনও ইন্টারফেস ব্যবহার করতে পারবেন না। সুতরাং এই উদাহরণে আপনার শ্রেণি বাস্তবায়িত হবে MyType(যেমন হিসাবে class Foo implements MyType)। বিদ্যমান জেএস কোডটি বর্ণনা করার সময় স্থিতিশীল ইন্টারফেস সংজ্ঞাগুলিতে কেবল আসল কার্যকর।
— বার্টভিডস

টাইপসক্রিপ্ট 1.5 প্রকাশের পরে এই মুহুর্তে (6.15.2015), এখানে কোনও শ্রেণীর স্থির সদস্যদের বর্ণনা করার একটি কার্যক্ষম উপায়। stackoverflow.com/a/43674389/681830
— Val,

4

আপনি যদি কোনও স্ট্যাটিক শ্রেণি সংজ্ঞায়িত করতে খুঁজছেন (যেমন, সমস্ত পদ্ধতি / বৈশিষ্ট্য স্থিতিশীল), আপনি এই জাতীয় কিছু করতে পারেন:

interface MyStaticClassInterface {
  foo():string;
}

var myStaticClass:MyStaticClassInterface = {
  foo() {
    return 'bar';
  }
};

এই ক্ষেত্রে, স্থিতিশীল "শ্রেণি" সত্যই কেবল একটি সরল-ওল-জেএস-অবজেক্ট, যা সমস্ত পদ্ধতি প্রয়োগ করে MyStaticClassInterface


4

হ্যা এটা সম্ভব. সমাধান এখানে

export interface Foo {

    test(): void;
}

export namespace Foo {

    export function statMethod(): void {
        console.log(2);
    }

}

এটা সত্যিই দারুন! হুবহু আমার যা প্রয়োজন
— উমর ফারুক খাজা

1
@ উমরফরুকখাজাওয়া আমি সাহায্য করে খুশি!
— পাভেল_কে

সুতরাং এটি Fooএকটি শ্রেণি সংজ্ঞা জন্য দাঁড়ানোর জন্য একটি নেমস্পেস ব্যবহার করে ? যেখানে ক্লাস ফু স্টেটমেথোদ প্রয়োগ করবে () এটি কিছুটা হ্যাক মনে হয়, esp যেহেতু নেমস্পেসগুলি এখন এক ধরণের
— অবহেলিত

@ ডিসিএসান হ্যাঁ, এটি কিছুটা হ্যাক। তবে কি করব? টাইপস্ক্রিপ্টের প্রচুর ইস্যু বহু বছর ধরে লেবেল সহ খোলা থাকে waiting more feedback। সুতরাং আপনি হয় স্থির পদ্ধতি ইন্টারফেসে যুক্ত না হওয়া পর্যন্ত অপেক্ষা করুন বা এইভাবে করুন।
— পাভেল_কে

তবে আমিও এটি পুরোপুরি পাই না .. export namespaceআসলেই কি আপনার ক্লাস বাস্তবায়ন? এটি জিনিসগুলি অনেকটা বাঁকানো বলে মনে হচ্ছে। আমি ভাবছি ক্লাসে ভাঙ্গা আর কী?
— dcsan

3

এখানে উল্লিখিত না হওয়া অন্য একটি বিকল্পটি স্থির ইন্টারফেসের প্রতিনিধিত্ব করে এমন একটি ধরণের সাথে ভেরিয়েবল সংজ্ঞায়িত করা এবং এটির জন্য শ্রেণীর এক্সপ্রেশন নির্ধারণ:

interface MyType {
    instanceMethod(): void;
}

interface MyTypeStatic {
    new(): MyType;
    staticMethod(): void;
}

// ok
const MyTypeClass: MyTypeStatic = class MyTypeClass {
    public static staticMethod() { }
    instanceMethod() { }
}

// error: 'instanceMethod' is missing
const MyTypeClass1: MyTypeStatic = class MyTypeClass {
    public static staticMethod() { }
}

// error: 'staticMethod' is missing
const MyTypeClass2: MyTypeStatic = class MyTypeClass {
    instanceMethod() { }
}

প্রভাব সজ্জিতগুলির সাথে উত্তর হিসাবে একই , তবে সজ্জকারগুলির ওভারহেড ছাড়াই

খেলার মাঠ

গিটহাব সম্পর্কিত প্রাসঙ্গিক পরামর্শ / আলোচনা


2

আপনি একই নামটি ব্যবহার করে নেমস্পেসের সাথে ইন্টারফেস একীভূত করতে পারেন :

interface myInterface { }

namespace myInterface {
  Name:string;
}

তবে এই ইন্টারফেসটি কেবল তার সম্পত্তি আছে তা জানতে দরকারী Name। আপনি এটি বাস্তবায়ন করতে পারবেন না।


2

আমি আমার নির্দিষ্ট ব্যবহারের ক্ষেত্রে এটি করার (সজ্জা ছাড়াই) উপায় খুঁজে পেয়েছি।

স্থিতিশীল সদস্যদের জন্য যে গুরুত্বপূর্ণ অংশটি পরীক্ষা IObjectClassকরে তা হ'ল এবং পদ্ধতিতে ব্যবহার cls: IObjectClass<T>করা createObject:

//------------------------
// Library
//------------------------
interface IObject {
  id: number;
}
interface IObjectClass<T> {
  new(): T;
  table_name: string;
}
function createObject<T extends IObject>(cls: IObjectClass<T>, data:Partial<T>):T {
  let obj:T = (<any>Object).assign({},
    data,
    {
      id: 1,
      table_name: cls.table_name,
    }
  )
  return obj;
}

//------------------------
// Implementation
//------------------------
export class User implements IObject {
  static table_name: string = 'user';
  id: number;
  name: string;
}

//------------------------
// Application
//------------------------
let user = createObject(User, {name: 'Jimmy'});
console.log(user.name);

0

যদিও স্ট্যাটিক কীওয়ার্ড টাইপস্ক্রিপ্টে ইন্টারফেসে সমর্থিত নয় তবে আমরা function interfaceস্থির সদস্য রয়েছে এমনটি তৈরি করে এটি অর্জন করতে পারি ।

আমার নিম্নলিখিত কোডটিতে আমি একটি ফাংশন ইন্টারফেস তৈরি Factoryকরেছি যার দুটি স্ট্যাটিক সদস্য serialNumberএবং প্রিন্টসেরিয়াল রয়েছে ।

// factory is a function interface
interface Factory<T> {
    (name: string, age: number): T;

    //staic property
    serialNumber: number;

    //static method
    printSrial: () => void;
}

class Dog {
    constructor(public name: string, public age: number) { }
}

const dogFactory: Factory<Dog> = (name, age) => {
    return new Dog(name, age);
}

// initialising static members

dogFactory.serialNumber = 1234;
dogFactory.printSrial = () => console.log(dogFactory.serialNumber);


//instance of Dog that DogFactory creates
const myDog = dogFactory("spike", 3);

//static property that returns 1234
console.log(dogFactory.serialNumber)

//static method that prints the serial 1234
dogFactory.printSrial();

0

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

সমাধানটি হ'ল:

interface MyInterface {
    Name: string;
}

const MyClass = class {
    static Name: string;
};

তবে, শ্রেণীর এক্সপ্রেশন ব্যবহার আমাকে MyClassধরণের হিসাবে ব্যবহারের অনুমতি দেয় না । আমি যদি কিছু লিখি:

const myInstance: MyClass;

myInstanceপ্রকারভেদে পরিণত হয় anyএবং আমার সম্পাদকটি নিম্নলিখিত ত্রুটিটি দেখায়:

'MyClass' refers to a value, but is being used as a type here. Did you mean 'typeof MyClass'?ts(2749)

ক্লাসের স্থির অংশের জন্য ইন্টারফেসের সাথে আমি যেটি অর্জন করতে চেয়েছিলাম তার চেয়ে গুরুত্বপূর্ণ টাইপিংটি আমি হারিয়ে ফেলছি।

সাজসজ্জার ব্যবহার করে ভ্যালির সমাধান এই ক্ষতিটিকে এড়িয়ে চলে।

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