আমার কাছে একটি লাইব্রেরি রয়েছে যা নিম্নলিখিতগুলির মতো একটি ইউটিলিটি ধরণের রফতানি করে:
type Action<Model extends object> = (data: State<Model>) => State<Model>;
এই ইউটিলিটি ধরণ আপনাকে এমন কোনও ক্রিয়া ঘোষণা করতে দেয় যা "ক্রিয়া" হিসাবে সম্পাদন করবে perform এটি Modelক্রিয়াকলাপটির বিরুদ্ধে কাজ করবে এমন একটি জেনেরিক যুক্তি পেয়েছে ।
data"এক্সন" এর আর্গুমেন্টটি পরে আমি রফতানি করে এমন আরও একটি ইউটিলিটি টাইপ করা হয়;
type State<Model extends object> = Omit<Model, KeysOfType<Model, Action<any>>>;
Stateউপযোগ টাইপ মূলত ইনকামিং লাগে Modelজেনেরিক এবং তারপর একটি নতুন ধরনের যেখানে সব বৈশিষ্ট্য যে ধরনের সৃষ্টি Actionসরানো হয়েছে।
উদাহরণস্বরূপ, এখানে উপরোক্ত একটি মৌলিক ব্যবহারকারীর জমি বাস্তবায়ন;
interface MyModel {
counter: number;
increment: Action<Model>;
}
const myModel = {
counter: 0,
increment: (data) => {
data.counter; // Exists and typed as `number`
data.increment; // Does not exist, as stripped off by State utility
return data;
}
}
উপরেরটি খুব ভালভাবে কাজ করছে। 👍
তবে, এমন একটি মামলা রয়েছে যার সাথে আমি লড়াই করছি, বিশেষত যখন জেনেরিক মডেলের সংজ্ঞা সংজ্ঞায়িত করা হয়, জেনেরিক মডেলের উদাহরণ তৈরি করার জন্য একটি কারখানা ফাংশন সহ।
উদাহরণ স্বরূপ;
interface MyModel<T> {
value: T; // 👈 a generic property
doSomething: Action<MyModel<T>>;
}
function modelFactory<T>(value: T): MyModel<T> {
return {
value,
doSomething: data => {
data.value; // Does not exist 😭
data.doSomething; // Does not exist 👍
return data;
}
};
}
উপরের উদাহরণে আমি প্রত্যাশাটি dataযুক্তিটি টাইপ করা হবে যেখানে doSomethingকর্মটি সরানো হয়েছে, এবং জেনেরিক valueসম্পত্তি এখনও বিদ্যমান exists এটি তবে এটি নয় - valueসম্পত্তিটিও আমাদের Stateইউটিলিটি দ্বারা সরানো হয়েছে ।
আমি বিশ্বাস করি যে এর কারণটি Tহ'ল জেনেরিক যে কোনও প্রকারের সীমাবদ্ধতা / সংকীর্ণতা প্রয়োগ না করেই প্রয়োগ করা হয় এবং তাই টাইপ সিস্টেমটি সিদ্ধান্ত নেয় যে এটি কোনও Actionপ্রকারের সাথে ছেদ করে এবং পরবর্তীকালে এটি dataআর্গুমেন্টের ধরণ থেকে অপসারণ করে ।
এই বিধিনিষেধের কাছাকাছি যাওয়ার কোনও উপায় আছে কি? আমি কিছু গবেষণা করেছি এবং আশা করছিলাম যে এমন কোনও প্রক্রিয়া থাকবে যাতে আমি বলতে পারি যে Tএটি ব্যতীত অন্য কোনও বিষয় Action। অর্থাত্ নেতিবাচক ধরণের সীমাবদ্ধতা।
কল্পনা করুন:
function modelFactory<T extends any except Action<any>>(value: T): UserDefinedModel<T> {
তবে সেই বৈশিষ্ট্যটি টাইপস্ক্রিপ্টের জন্য বিদ্যমান নেই।
আমি যেভাবে প্রত্যাশা করেছিলাম সেভাবে কাজ করতে এই উপায়টি কি কেউ জানেন?
এখানে ডিবাগিংয়ে সহায়তা করার জন্য একটি সম্পূর্ণ কোড স্নিপেট:
// Returns the keys of an object that match the given type(s)
type KeysOfType<A extends object, B> = {
[K in keyof A]-?: A[K] extends B ? K : never
}[keyof A];
// Filters out an object, removing any key/values that are of Action<any> type
type State<Model extends object> = Omit<Model, KeysOfType<Model, Action<any>>>;
// My utility function.
type Action<Model extends object> = (data: State<Model>) => State<Model>;
interface MyModel<T> {
value: T; // 👈 a generic property
doSomething: Action<MyModel<T>>;
}
function modelFactory<T>(value: T): MyModel<T> {
return {
value,
doSomething: data => {
data.value; // Does not exist 😭
data.doSomething; // Does not exist 👍
return data;
}
};
}
আপনি এই কোড উদাহরণটি এখানে খেলতে পারেন: https://codesandbox.io/s/reverent-star-m4sdb?foutsize=14