TypeScript - پارامتر از نوع اتحادیهی انومها؟
آنچه من دارم دو شمارش هستند
enum Fruit { Apples, Oranges };
enum Vegetable { Garlic, Cucumber };
و یک نوع
type Food = Fruit | Vegetable;
حال میخواهم نوع دیگری بسازم که یک تابع باشد و یک غذا را به عنوان پارامتر دریافت کند
type OnViewFood = (food: Food) => void;
اما وقتی انجام میدهم
viewFruit: OnViewFood = (fruit: Fruit) => `This is ${fruit}`;
من یک خطا دریافت میکنم که Food قابل اختصاص دادن به Fruit نیست. چگونه میتوانم به هدفم برسم؟
پاسخ شماره ۱
دلیل اینکه کامپایلر نمیخواهد شما این کار را انجام دهید این است که اساساً ایمن نیست. تصور کنید اگر این مثال معتبر بود:
// we assign a function that can only handle Fruit.
let viewFruit: OnViewFood = (fruit: Fruit) => `This is ${fruit}`;
// the declared signature allows us to use a Vegetable,
// possibly causing an error
viewFruit(Vegetable.Cucumber);
شما میتوانید OnViewFood را به عنوان یک اجتماع از توابع اعلام کنید، اما در این صورت فراخوانی آن مشکل میشود زیرا نمیتوانید یک اجتماع از توابع را فراخوانی کنید و همچنین نمیتوانید بهراحتی از محافظت نوع استفاده کنید:
type OnViewFood = ((food: Fruit) => void) | ((food: Vegetable) => void);
let viewFruit: OnViewFood = (fruit: Fruit) => `This is ${fruit}`;
// ok now can be either function signature
viewFruit(Vegetable.Cucumber); // now an error
در هر دو صورت میتوانیم از تایپ اسرتیشن استفاده کنیم تا از خطای نوع عبور کنیم، و میتوانید به هر گزینهای بروید، بسته به اینکه بیشتر به کدام طرف اعتماد دارید، طرف ایجادکننده تابع یا طرف فراخواننده:
// Type assertion on call
type OnViewFood = ((food: Fruit) => void) | ((food: Vegetable) => void);
let viewFruit: OnViewFood = (fruit: Fruit) => `This is ${fruit}`;
(viewFruit as any as ((food: Vegetable) => void))(Vegetable.Cucumber);
// Type assertion on declaration
type OnViewFood = (food: Food) => void
let viewFruit: OnViewFood = ((fruit: Fruit) => `This is ${fruit}`) as (food: Food) => void;
viewFruit(Vegetable.Cucumber);
