简体   繁体   English

在TypeScript中,是否有任何方法可以将函数返回值键入函数本身?

[英]In TypeScript, is there any method to type function return values to the function itself?

For the last week, I've been researching how it could be possible to type function return values to the funtion itself in TypeScript. 在上周,我一直在研究如何在TypeScript中将函数返回值键入函数本身。

What is hard to me is types are not the first-class object in TypeScript(or any other type systems, not sure). 对我来说,很难的是类型不是TypeScript(或其他任何类型的系统,不是很确定)中的一流对象。

In a sense, I'm seeking a way for Self-reference types; 从某种意义上说,我正在寻找一种自我参照类型的方法。 not only identifies itself but also distinguishes from any others. 不仅可以识别自己,而且可以与其他任何人区分开。

In fact, I've implemented such a thing in vanilaJS. 实际上,我已经在vanilaJS中实现了这样的事情。

example1: Member type to a return value of a function: Member 示例1: Member类型为函数的返回值: Member

log("=Are you a member? ========= ");
const Member = a => Type(Member)([a]); // Member = a=>[a]

const alice = ["Alice"];
const bob = Member("Bob"); //["Bob"]

log(
    isType(Member)(alice)
);//false
log(
    isType(Member)(bob)
);//true

example2: specialOperation type to a certain functions example2:对特定功能的specialOperation类型

log("=Is this a special operation? ========= ");
const specialOperation = f => Type(specialOperation)(f);

const f1 = a => a + 1; //vanilla function
const f2 = Type(specialOperation) //typed function
    (a => {
        //This function might be considered to be "special" 
        //because it does some featured operations in a context.
        return a * 2;
    });

log(
    isType(specialOperation)(f1)
);//false
log(
    isType(specialOperation)(f2)
);//true
log(
    f2(1) // f2 = a => a * 2
);//2  // just in case, let you know

exapmples and test 实例和测试

 //--- debug use const log = (m) => { console.log(m); //IO return m; }; //---- a type sysetm in vanillaJS const typedPrimitive = T => i => { const derived = Object(i); Object.setPrototypeOf(derived, Object(i)); const typeProperty = { enumerable: false, configurable: false, writable: false, value: true }; Object.defineProperty(derived, T, typeProperty); return derived; }; const typedObject = T => i => { const handler = { get: (target, name) => name == T//must == ? true : target[name] }; return new Proxy(i, handler); }; const typed = T => i => (i !== Object(i))//primitives ? typedPrimitive(T)(i) : typedObject(T)(i) const istype = T => i => i[T] === true; const Type = T => i => (i === T) || (i == null) ? i : typed(T)(i); const isType = T => i => (i === T) ? true : (i == null) ? false : istype(T)(i); //------------------------------------------ log("=Are you a member? ========= "); const Member = a => Type(Member)([a]); // M = a=>[a] const alice = ["Alice"]; const bob = Member("Bob"); //["Bob"] log( isType(Member)(alice) );//false log( isType(Member)(bob) );//true log("=Is this a special operation? ========= "); const specialOperation = f => Type(specialOperation)(f); const f1 = a => a + 1; //vanilla function const f2 = Type(specialOperation) //typed function (a => { //This function might be considered to be "special" //because it does some featured operations in a context. return a * 2; }); log( isType(specialOperation)(f1) );//false log( isType(specialOperation)(f2) );//true log( f2(1) // f2 = a => a * 2 );//2 // just in case, let you know log("=type test of nontyped========================="); const I = a => a; //just a dummy function log( isType(I)(I) // true ); log( isType(I)(1) // false ); log( isType(I)([]) // fakse ); log( isType(I)({}) // false ); log( isType(I)("hello") //fakse ); log( isType(I)(x => x) // false ); log( isType(I)(true) // false ); log( isType(I)(false) // false ); log("=type test of typed========================="); log( isType(I)(Type(I)(I)) // true ); log( isType(I)(Type(I)(1)) // true ); log( isType(I)(Type(I)([])) // true ); log( isType(I)(Type(I)({})) // true ); log( isType(I)(Type(I)("hello")) //true ); log( isType(I)(Type(I)(x => x)) // true ); log( isType(I)(Type(I)(true)) // true ); log( isType(I)(Type(I)(false)) // true ); log( (Type(I)(false) == false) ? "Type(I)(false) == false (as should be)" : "something is wrong" ); log( (Type(I)(false) !== false)//Object !== Primitive ? "Type(I)(false) !== false (as should be)" : "something is wrong" ); log( isType(I)(Type(I)(NaN)) //true ); log( isType(I)(Type(I)(undefined)) // false ); log( isType(I)(Type(I)(null)) // false ); log( Type(I)(1) + Type(I)(2)//3 ); log( Type(I)([1, 2, 3]) );//[1, 2, 3] 

Although I think this method is quite useful in JavaScript, and the code runs also in TypeScript, I wonder if it's possible to implement in a sophisticated TypeScript way, because if there is better and "native manner" to do this in TypeScript, mixing another implementation by my own should be quite redundant. 尽管我认为该方法在JavaScript中非常有用,并且代码也可以在TypeScript中运行,但我想知道是否可以以复杂的TypeScript方式实现,因为如果有更好的“本机”方式在TypeScript中实现,则可以混合使用由我自己执行应该是多余的。

Thank you. 谢谢。

This can be accomplished with conditional types introduced in typescript 2.8: 这可以通过打字稿2.8中引入的条件类型来实现:

let someFunction: () => String;
let x : ReturnType<typeof someFunction>;

In case you are curious about the design alternatives the typescript team considered, the discussion in #6606 provides a good overview. 如果您对打字稿小组考虑的设计替代方案感到好奇,请参阅#6606中的讨论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM