কোনও ফাংশনের রিটার্ন টাইপ প্রাপ্ত


101

আমি নিম্নলিখিত ফাংশন আছে:

function test(): number {
    return 42;
}

আমি ব্যবহার করে ফাংশনের ধরণটি পেতে পারি typeof:

type t = typeof test;

এখানে, tহবে () => number

ফাংশনটির রিটার্ন টাইপ পাওয়ার কোনও উপায় আছে কি? আমি পরিবর্তে tহতে চাই ।number() => number


4
না, যাইহোক টাইপের সাথে নয়। টাইপফ শুধুমাত্র "ফাংশন" ফিরিয়ে দেবে ( আমার কেসিং ভুল হতে পারে )।
ইগোর

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

উত্তর:


164

সম্পাদনা

টাইপস্ক্রিপ্ট ২.৮ অনুসারে এটি আনুষ্ঠানিকভাবে সম্ভব ReturnType<T>

type T10 = ReturnType<() => string>;  // string
type T11 = ReturnType<(s: string) => void>;  // void
type T12 = ReturnType<(<T>() => T)>;  // {}
type T13 = ReturnType<(<T extends U, U extends number[]>() => T)>;  // number[]

বিশদ জন্য এখানে দেখুন ।

টাইপস্ক্রিপ্ট দুর্দান্ত!


ওল্ড স্কুল হ্যাক

দুর্ভাগ্যক্রমে রায়ের উত্তর আর কাজ করে না। তবে আমি এটিকে একটি হ্যাক দিয়ে সংশোধন করেছি যা সম্পর্কে আমি অযৌক্তিকভাবে খুশি। দেখুন:

const fnReturnType = (false as true) && fn();

এটি সত্যের আক্ষরিক মানকে মিথ্যা castালাই দিয়ে কাজ করে, যাতে টাইপ সিস্টেমটি মনে করে যে রিটার্নের মানটি ফাংশনের ধরণ, তবে আপনি যখন কোডটি আসলে চালাবেন, এটি মিথ্যাতে শর্ট সার্কিট।

টাইপস্ক্রিপ্ট সেরা। : ডি


53
যীশু, এটা ভয়াবহ।
জন ওয়েইজ

প্রবাহের জন্য: কনস্ট DUMMY = ((নাল: যে কোনও): অবজেক্ট) && fn () রফতানির ধরণ = টাইপের ডামি
ডেভিড জিউ

কোন ধারণা কেন যখন আমি 2.8 ইনস্টল এবং আমি নিম্নলিখিত ত্রুটি পেতে চেষ্টা করুন: Cannot find name 'ReturnType'? vscode ব্যবহার করে
এনএসজোনাস

4
অন্যান্য সংস্করণটি ব্যবহার করার জন্য আপনাকে এনএনএস জোনাসকে vscode বলতে হবে। আমি মনে করি তিনি নীচে ডানদিকে স্ট্যাটাস বার।
মেরিওন হিউজ

12
আমাকে করতে হয়েছিল ReturnType<typeof fn>(উত্তরটি বোঝায় ReturnType<fn>যথেষ্ট)।
spacek33z

49

টাইপস্ক্রিপ্ট ২.৮-এর সহজতম উপায়:

const foo = (): FooReturnType => {
}

type returnType = ReturnType<typeof foo>;
// returnType = FooReturnType

5

নীচের কোডটি ফাংশনটি কার্যকর না করেই কাজ করে। এটি প্রতিক্রিয়া-রিডেক্স-টাইপস্রিপ্ট লাইব্রেরি থেকে এসেছে ( https://github.com/alexzywiak/react-redux-typescript/blob/master/utils/redux/typeUtils.ts )

interface Func<T> {
    ([...args]: any, args2?: any): T;
}
export function returnType<T>(func: Func<T>) {
    return {} as T;
}


function mapDispatchToProps(dispatch: RootDispatch, props:OwnProps) {
  return {
    onFinished() {
      dispatch(action(props.id));
    }
  }
}

const dispatchGeneric = returnType(mapDispatchToProps);
type DispatchProps = typeof dispatchGeneric;

4

এটি করার কোনও উপায় নেই ( কাজের আইটেম ট্র্যাকিংয়ের জন্য এটি যুক্ত করার জন্য https://github.com/Mic Microsoft/TypeScript/issues/6606 দেখুন)।

একটি সাধারণ কর্মক্ষেত্র হ'ল কিছু লিখুন:

var dummy = false && test();
type t2 = typeof dummy;

4
আমি মনে করি না যে এই কাজটি আর কাজ করবে না - সম্ভবত নিয়ন্ত্রণ প্রবাহ ভিত্তিক প্রকার-বিশ্লেষণের কারণে।
জিলিবিয়ান

4
@JKillian আপনি ঠিক, উদাহরণস্বরূপ প্রস্তাবিত আর কাজ যদিও আপনি সহজেই সঙ্গে টাইপ করা বিষয় রত পারেন !1পরিবর্তে false- typescriptlang.org/play/...
DanielM

3

সম্পাদনা: এটি আর আর ২.৮ টিএসের প্রয়োজন নেই! ReturnType<F>রিটার্ন টাইপ দেয়। গৃহীত উত্তর দেখুন।


পূর্ববর্তী কয়েকটি উত্তর যা আমি ব্যবহার করছি তার একটি বৈকল্পিক, যা strictNullChecksইনফারেন্স জিমন্যাস্টিকগুলিতে কাজ করে এবং কিছুটা আড়াল করে:

function getReturnType<R>(fn: (...args: any[]) => R): R {
  return {} as R;
}

ব্যবহার:

function foo() {
  return {
    name: "",
    bar(s: string) { // doesn't have to be shorthand, could be `bar: barFn` 
      return 123;
    }
  }
}

const _fooReturnType = getReturnType(foo);
export type Foo = typeof _fooReturnType; // type Foo = { name: string; bar(s: string): number; }

এটা তোলে নেই কল getReturnTypeফাংশন, কিন্তু এটা না মূল ফাংশন কল। আপনি পারে প্রতিরোধ getReturnTypeব্যবহার কল (false as true) && getReturnType(foo)কিন্তু আইএমও এই মাত্র এটা আরো বিভ্রান্তিকর তোলে।

আমি এই পদ্ধতিটি কিছু পুরানো অ্যাঙ্গুলার 1.x প্রোজেক্টে স্থানান্তরিত করার জন্য কিছু রিজেপেক্সের সাথে সন্ধান / প্রতিস্থাপনের সাথে ব্যবহার করেছি, মূলত জেএস-তে এই জাতীয় 1500 ডলারের ফ্যাক্টরি ফাংশন লেখা হয়েছিল এবং Fooসমস্ত প্রকারের সাথে এই জাতীয় প্রকারগুলি যুক্ত করেছে ... ভাঙা কোডটি এক আশ্চর্যজনক খুঁজে পাবে। :)


ধন্যবাদ! দুঃখজনক হলেও এটি এই পরিমাণ ভারবাইজ লাগে, এটি কমপক্ষে কাজ করে!
ইকমানাট

@ একমানাউট আমাদের আর এটির দরকার নেই! টিএস ২.৮ এ আপনি ReturnType<F>কোনও ফাংশন রিটার্ন টাইপ পেতে ব্যবহার করতে পারেন । :)
অ্যারন বেল

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

1

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

উদাহরণস্বরূপ, আপনি এটি কনসোলে লগ করতে পারেন:

function logReturnType(
    target: Object | Function,
    key: string,
    descriptor: PropertyDescriptor
): PropertyDescriptor | void {
    var returnType = Reflect.getMetadata("design:returntype", target, key);

    console.log(returnType);
}

আপনার পছন্দের একটি পদ্ধতিতে কেবল এই পদ্ধতিটি ডেকরেটারকে স্ন্যাপ করুন এবং আপনার কাছে অবজেক্টের কন্সট্রাক্টর ফাংশনের সঠিক রেফারেন্স রয়েছে যা অনুমানিত পদ্ধতি কল থেকে ফিরে এসেছে।

class TestClass {
    @logReturnType // logs Number (a string representation)
    public test(): number {
        return 42;
    }
}

তবে এই পদ্ধতির কয়েকটি উল্লেখযোগ্য সীমাবদ্ধতা রয়েছে:

  • আপনাকে যেমন সাজানো কোনও পদ্ধতিতে পরিষ্কারভাবে রিটার্নের ধরণটি সংজ্ঞায়িত করতে হবে, অন্যথায় আপনি এ থেকে সংজ্ঞায়িত হয়ে যাবেন Reflect.getMetadata,
  • আপনি কেবল প্রকৃত প্রকারগুলিই উল্লেখ করতে পারেন যা সংকলনের পরেও বিদ্যমান; এটি কোনও ইন্টারফেস বা জেনেরিকস নয়

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

--emitDecoratorMetadata --experimentalDecorators

0

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


4
যদিও এটি প্রযুক্তিগতভাবে সত্য যে টিএস রানটাইম চলাকালীন ধরণের তথ্য হারায়, তবে এই সত্যটি প্রাসঙ্গিক নয়, কারণ ওপি সংকলনের সময় ফাংশনের ধরণটি নির্ধারণ করতে চায়। এটি এখন আরও ReturnType<T>স্পষ্টত যা টাইপস্ক্রিপ্টে প্রয়োগ করা হয়েছে।
দিনদিনগুলি

0

আমি নিম্নলিখিতটি নিয়ে এসেছি, যা দেখতে সুন্দরভাবে কাজ করছে:

function returnType<A, B, Z>(fn: (a: A, b: B) => Z): Z
function returnType<A, Z>(fn: (a: A) => Z): Z
function returnType<Z>(fn: () => Z): Z
function returnType(): any {
    throw "Nooooo"
}

function complicated(value: number): { kind: 'complicated', value: number } {
    return { kind: 'complicated', value: value }
}

const dummy = (false as true) && returnType(complicated)
type Z = typeof dummy

4
আমি মনে করি না যে ফাংশন আরগগুলি জেনেরিক হওয়া দরকার, যেহেতু আপনি যেভাবেই এগুলি ফেলে দিচ্ছেন। fn: (...args: any[]) => Zআপনার যা দরকার তা হল।
অ্যারন বেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.