转换对象属性,以便在typescript中保留隐式类型

转换对象属性,以便在typescript中保留隐式类型,types,typescript,Types,Typescript,我正在寻找一种转换函数或方法,它允许我保留typescript在结果对象上推断类型(获取类型检查和代码提示)的能力。在下面的例子中,C(和相关的E)是被证明有问题的场景 class Wrapper<T> { constructor(private val: T) { } value(): T { return this.val; } } // A var wrappedNum = new Wrapper(1); // Typescript

我正在寻找一种转换函数或方法,它允许我保留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); 
类包装器{
构造函数(私有val:T){}
值():T{
返回此.val;
}
}
//A
var wrappedNum=新包装(1);
//Typescript推断value()并返回一个数字
wrappedNum.value().toFixed(1);
//B
var wrappedNumArray=[1,2,3].map(函数(val){returnnewwrapper(val);});
//Typescript推断,对于数组中的每个元素,value()返回数字
wrappedNumArray[0].value().toFixed(1);
//C
//**在此转换中,属性类型丢失**
函数包装对象(obj){
var targ={};
for(obj中的var键){
targ[key]=新包装(obj[key]);
}
返回目标;
}
var wrappedObj=wrapObject({a:1});
//Typescript不能推断wrappedObj上是否存在“a”
wrappedObj.a;
//D
//Typescript推断“a”及其类型
({a:1}).a.toFixed(1);
//E
//**在此转换中,属性类型丢失**
函数noop(obj){
返回obj;
}
//Typescript不会推断noop转换对象上是否存在“a”
noop({a:1}).a;
//F
函数getValue(){
返回{a:1};
}
//Typescript推断“a”及其类型的存在
getValue().a.toFixed(1);
是否有一种方法可以构造C&E,使类型推断在不知道所传递对象的结构的情况下工作?

C

对于C,我想不出一个方法来做到这一点。一种折衷方法是使用A,然后用泛型将其映射出来

例如:

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
函数wrapObject(对象:T){
var target:{[key:string]:包装器;}={};
for(obj中的var键){
targ[key]=新包装(obj[key]);
}
返回目标;
}
var wrappedObj=wrapObject({a:1});
wrappedObj[“a”].值;//好啊
E

使用泛型:

function noop<T>(obj: T) {
    return obj;
}

noop({ a: 1 }).a; // works
函数noop(obj:T){
返回obj;
}
noop({a:1}).a;//作品

在.

Hmmm中阅读有关泛型的更多信息。这对E是正确的,但对C是错误的
wrappedObj.a
似乎有一个推断的
number
类型,但实际上是一个
包装器
。此类型系统强制与
wrapObject
@bjnsn上的返回类型注释相匹配,但忽略了该细节。就我现在所能想到的,这是不可能做到的。谢谢你的努力。我一直在绞尽脑汁,也没想到什么。我希望有人谁是更熟悉的打字稿比我会猛扑!