是否可以从Typescript中的类型推断的参数中提取键?

时间:2017-11-20 09:10:39

标签: typescript

我试图从一个对象中提取一些属性 应该提取的键作为函数的参数给出。

例如,对于此代码,它从对象复制特定键并返回new,另一个具有相同键的对象。

function pick(source: object, ...keys: string[]) {
    const returnValue = {} 
    for (const key in source) {
        const index = keys.indexOf(key)
        if (index < 0) continue
        keys.splice(index, 1)
        returnValue[ key ] = source[ key ]
    }
    return returnValue
}

当我使用此函数时,TypeScript将返回类型推断为{},这是一个空对象。有没有办法可以将其作为{ [key: .. in parameter 'keys' ..]: any }

我尝试了这个,但它没有用。

function pick<O>(source: object, ...keys: (keyof O)[]): O {
    const returnValue: O = {} 
    for (const key in source) {
        const index = keys.indexOf(key)
        if (index < 0) continue
        keys.splice(index, 1)
        returnValue[ key ] = source[ key ]
    }
    return returnValue
}

谢谢

3 个答案:

答案 0 :(得分:1)

在TypeScript 2.1中添加了内置Pick类型,完全用于描述此类函数:

function pick<T, K extends keyof T>(source: T, ...keys: K[]): Pick<T, K> {

仅供参考,它是一个非常简单的mapped type定义为

type Pick<T, K extends keyof T> = {[k in K]: T[k]};

但是,如果没有类型转换,您的实现就无法编译,因为TypeScript抱怨keys.indexOf(key) - key现在是keyof T,并且它与indexOf参数的类型不兼容,这是keys元素类型 - K

所以我用一个遍历keys数组的循环实现了稍微不同的实现。我不会从keys删除“已使用”的密钥 - 如果有重复项(我认为这不太可能),则在此处分配相同的值将不会造成任何损害:

function pick<T, K extends keyof T>(source: T, ...keys: K[]): Pick<T, K> {
    const returnValue = {} as Pick<T, K>;
    keys.forEach(k => {
        returnValue[k] = source[k];
    });
    return returnValue;
}

答案 1 :(得分:0)

我认为你可以在对象之间做一个简单的映射器:

interface OriginalObject {
  property1: string
  property2: string
  property3: string
}

interface MappedObject {
   mappedProperty1: string,
   mappedProperty2: string
}

class Mapper {
   static mapOriginalObjectToMappedObject(object: OrginalObject): MappedObject {
      return {
         mappedProperty1: object.property2, 
         mappedProperty2: object.property3
      }
   }

   static mapFooToBaz ...
   static mapBarToFoo ...
}

在您的代码中:

const objectA: OriginalObject = {
  property1: "foo",
  property2: "bar",
  property3: "baz"
}
const mappedObjectA = Mapper.mapOriginalObjectToMappedObject(objectA)

通过这种方式,您的代码保持简单

答案 2 :(得分:0)

如果你想解析&#34;使用相同键的两个对象,您应该使用Object.keys

让我们假设您有两个对象myObject和myOtherObj,如果键是相同的,只使用一个映射器:

Object.keys(myObject).map((key) => {
   console.log(key) // should be the same for both obj
   // your two obj values
   console.log(myObject[key]);
   console.log(myOtherObj[key]);
});

编辑:你也可以做Object.keys(myOtherObj).map ....