【问题标题】:In TypeScript, is there any method to type function return values to the function itself?在 TypeScript 中,是否有任何方法可以将函数返回值键入函数本身?
【发布时间】:2019-01-05 15:03:10
【问题描述】:

上周,我一直在研究如何在 TypeScript 中将函数返回值键入到函数本身。

对我来说困难的是类型不是 TypeScript(或任何其他类型系统,不确定)中的第一类对象。

从某种意义上说,我正在寻找一种自引用类型的方法;不仅识别自己,而且区别于任何其他人。

其实我已经在 vanilaJS 中实现了这样的东西。

example1: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 输入某个函数

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

示例和测试

//--- 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]

虽然我认为这种方法在 JavaScript 中非常有用,并且代码也可以在 TypeScript 中运行,但我想知道是否可以用复杂的 TypeScript 方式来实现,因为在 TypeScript 中是否有更好的“原生方式”来做到这一点,我自己混合另一个实现应该是相当多余的。

谢谢。

【问题讨论】:

  • Typescript 类型仅在编译时存在。您是在问如何在编译器检查的类型保护中使用函数的返回类型,或者如何在运行时发现函数的返回类型?
  • 谢谢。正如您所提到的,TypeScript 是静态的,当然,从这个意义上说。 ,如何在编译器检查的类型保护中使用函数的返回类型

标签: javascript typescript types functional-programming


【解决方案1】:

这可以通过 typescript 2.8 中引入的conditional types 来完成:

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

如果您对 typescript 团队考虑的设计替代方案感到好奇,#6606 中的讨论提供了一个很好的概述。

【讨论】:

  • 谢谢你,可能你很清楚,但如果你能添加一些基本的代码用法会更有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 2021-08-30
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 2019-03-28
相关资源
最近更新 更多