【问题标题】:Transform object properties such that implicit typing is retained in typescript转换对象属性,以便在打字稿中保留隐式类型
【发布时间】:2015-12-13 11:07:00
【问题描述】:

我正在寻找一种转换函数或方法,它允许我保留 typescript 在结果对象上推断类型(获取类型检查和代码提示)的能力。在下面的示例中,C(和相关的 E)是被证明有问题的场景。

class Wrapper<T> {
    constructor(private val: T) { }

    value(): T {
        return this.val;
    }
}

// A 
var wrappedNum = new Wrapper(1);
// Typescript infers value() and that it returns a number
wrappedNum.value().toFixed(1); 

// B
var wrappedNumArray = [1, 2, 3].map(function(val) { return new Wrapper(val); });
// Typescript infers that for each element in array, value() returns number
wrappedNumArray[0].value().toFixed(1); 

// C
// ** Typing of properties is lost in this transformation **
function wrapObject(obj) {
    var targ = {};

    for(var key in obj) {
        targ[key] = new Wrapper(obj[key]);
    }

    return targ;
}

var wrappedObj = wrapObject({a: 1});
// Typescript does not infer the existence of `a` on wrappedObj
wrappedObj.a; 

// D
// Typescript infers `a` and its type
({ a: 1 }).a.toFixed(1); 

// E
// ** Typing of properties is lost in this transformation **
function noop(obj) {
    return obj;
}

// Typescript does not infer the existence of `a` on noop transformed object
noop({ a: 1 }).a; 

// F
function getValue() {
    return { a: 1 };
}

// Typescript infers the existence of `a` and its type
getValue().a.toFixed(1); 

有没有一种方法可以构建 C&E,使得类型推断可以在不知道传递的对象的结构的情况下工作?

【问题讨论】:

    标签: types typescript


    【解决方案1】:

    C

    对于 C,我想不出办法。一种折衷方案是使用dictionary-like type,然后用泛型映射出来。

    例如:

    function wrapObject<T>(obj: T) {
        var targ: { [key: string]: Wrapper<T>; } = {};
    
        for(var key in obj) {
            targ[key] = new Wrapper<T>(obj[key]);
        }
    
        return targ;
    }
    
    var wrappedObj = wrapObject({a: 1});
    wrappedObj["a"].value; // ok
    

    E

    使用泛型:

    function noop<T>(obj: T) {
        return obj;
    }
    
    noop({ a: 1 }).a; // works
    

    Handbook 中阅读有关泛型的更多信息。

    【讨论】:

    • 嗯。这对 E 是正确的 - 但对于 C 是不正确的。 wrappedObj.a 似乎具有推断的 number 类型,但实际上是 Wrapper&lt;number&gt;。这种类型系统强制符合wrapObject 上的返回类型注释。
    • @bjnsn 哎呀,错过了那个细节。就我现在能想到的,这是不可能的。
    • 感谢您的努力。我一直在绞尽脑汁,也没有想到什么。我希望有人比我更熟悉 Typescript!
    猜你喜欢
    • 2019-03-23
    • 2017-09-06
    • 2021-08-23
    • 2017-08-04
    • 2021-12-06
    • 2020-11-21
    • 1970-01-01
    • 2020-08-01
    • 2018-09-17
    相关资源
    最近更新 更多