TypeScript接口,其中对象键是另一个对象的值

时间:2018-03-05 17:59:07

标签: typescript

这是我的界面:

interface MyInterface {
    a: string
    b: string
}

我从这个界面获得objectA

const objectA: MyInterface = { 
    a: val1, 
    b: val2
}

然后我有一个函数读取API响应并创建映射,如下所示:

const createMapping = (response) => {
  const ret = {};
  response.forEach(item => {
    ret[objectA[item]] = true;
  })
 return ret;
}

有没有办法可以为createMapping的返回值创建一个接口,使接口的键值为MyIterface

返回值可以是{val1: true}{val2: true}{val1: true, val2:true}

3 个答案:

答案 0 :(得分:2)

我不确定objectA来自哪里,但你可以得到你想要的东西。首先,无论objectA来自何处,都应该让TypeScript知道值是特定的string literal types。有different ways来做这件事。最简单(但不是DRY)的方法是使用类型断言:

interface MyInterface {
  a: string
  b: string
}

const objectA = {
  a: "val1" as "val1",
  b: "val2" as "val2"
} 

请注意,objectA未注释为MyInterface,因为您不希望TypeScript忘记其属性为"val1""val2"。它与MyInterface的兼容性将在稍后验证。

现在我们可以创建一个函数,它接受任何MyInterface - 像(使用字符串属性)并生成一个使用它的createMapping()函数:

const makeCreateMapping = <O extends MyInterface & {[k: string]: string}>(o: O) =>
  (response: (keyof O)[]) => {
    const ret = {} as Partial<Record<O[keyof O], true>>;
    response.forEach(item => {
      ret[o[item]] = true;
    })
    return ret;
  }

O参数是MyInterface对象的类型。我们用makeCreateMapping()

致电objectA
const createMapping = makeCreateMapping(objectA);

这就是objectAMyInterface的事实。如果没有,编译器会对你大吼大叫。现在,如果您检查createMapping的类型,则为:

const createMapping: (response: ("a" | "b")[]) => Partial<Record<"val1" | "val2", true>>

即一个函数,它采用"a""b"数组,并返回一个基本上为Partial<Record<"val1" | "val2", true>>的{​​{1}},其有效值包括{val1?: true, val2?: true}{val1: true}{val2: true}

演示:

{val1: true, val2: true}

希望有所帮助。祝你好运!

答案 1 :(得分:1)

您只能在运行时获取API response值,此时您的TypeScript代码已编译成JavaScript,因此答案是:不,您将无法执行此操作。

答案 2 :(得分:0)

是的,您可以为箭头功能指定返回类型或界面。

const createMapping = (response): MyInterface => {
  const ret = {};
  response.forEach(item => {
    ret[objectA[item]] = true;
  })
return ret;
}

在这种情况下,当您执行函数createMapping时,输出(ret)应该是MyInterface类型。