转换对象属性,以便在TypeScript中保留隐式类型。
转换对象属性,以便在TypeScript中保留隐式类型。
我正在寻找一种转换函数或方法,可以让我保留TypeScript推断类型的能力(获得类型检查和代码提示)在结果对象上。在下面的示例中,C和相关的E是证明问题的情况。\n
class Wrapper{ constructor(private val: T) { } value(): T { return this.val; } } // A var wrappedNum = new Wrapper(1); // TypeScript推断value()返回一个数字 wrappedNum.value().toFixed(1); // B var wrappedNumArray = [1, 2, 3].map(function(val) { return new Wrapper(val); }); // TypeScript推断对于数组中的每个元素,value()返回数字 wrappedNumArray[0].value().toFixed(1); // C // **在这个转换中,属性的类型丢失了** function wrapObject(obj) { var targ = {}; for(var key in obj) { targ[key] = new Wrapper(obj[key]); } return targ; } var wrappedObj = wrapObject({a: 1}); // TypeScript没有推断出wrappedObj上存在`a` wrappedObj.a; // D // TypeScript推断出`a`及其类型 ({ a: 1 }).a.toFixed(1); // E // **在这个转换中,属性的类型丢失了** function noop(obj) { return obj; } // TypeScript没有推断出noop转换对象上存在`a` noop({ a: 1 }).a; // F function getValue() { return { a: 1 }; } // TypeScript推断出存在`a`及其类型 getValue().a.toFixed(1);
\n是否有一种方法可以使C和E的结构在保持对传递对象结构不可知的情况下,使类型推断工作?
问题:如何在TypeScript中使对象属性的隐式类型保持不变?
在上述内容中,提到了两种尝试解决这个问题的方法,分别是C和E。
在C中,作者提到了一种使用类似字典的类型并使用泛型进行映射的方法。具体实现是通过一个名为wrapObject的函数,接受一个泛型参数T和一个类型为T的对象obj。在函数内部,通过遍历obj的属性,并创建一个具有相同属性的对象targ,属性值为obj中对应属性的包装对象Wrapper
在E中,作者提到了使用泛型的方法。具体实现是通过一个名为noop的函数,接受一个泛型参数T和一个类型为T的对象obj。在函数内部,直接返回obj。通过这种方式,实现了对象属性的隐式类型保持不变。
然而,尽管E中的方法能够正确工作,但对于C而言却是错误的。在C中,wrappedObj.a表面上看起来是具有推断的number类型,但实际上是一个Wrapper
作者提到,目前他并没有想到其他解决这个问题的方法。他希望对TypeScript更熟悉的人能够提供帮助。
总结一下,问题是如何在TypeScript中使对象属性的隐式类型保持不变。解决方法有两种尝试,分别是使用字典和泛型。然而,使用字典的方法在某些情况下可能会导致类型错误。对于目前的问题,尚未找到其他解决方法。希望能够得到更多熟悉TypeScript的人的帮助。