这是我的界面:
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}
我不确定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);
这就是objectA
是MyInterface
的事实。如果没有,编译器会对你大吼大叫。现在,如果你检查createMapping
的类型,它是:
const createMapping: (response: ("a" | "b")[]) => Partial<Record<"val1" | "val2", true>>
也就是说,一个函数采用"a"
或"b"
的数组,并返回一个Partial<Record<"val1" | "val2", true>>
,其本质上是{val1?: true, val2?: true}
,其有效值包括{val1: true}
,{val2: true}
和{val1: true, val2: true}
。
展示:
declare const response: (keyof typeof objectA)[]
const mapping = createMapping(response);
mapping.val1 // true | undefined
mapping.val2 // true | undefined
mapping.val3 // error, doesn't exist
希望有所帮助。祝好运!
您只能在运行时获取API response
值,此时您的TypeScript代码已经编译成JavaScript,因此答案是:不,您将无法执行此操作。
是的,您可以为箭头功能指定返回类型或界面。
const createMapping = (response): MyInterface => {
const ret = {};
response.forEach(item => {
ret[objectA[item]] = true;
})
return ret;
}
在这种情况下,当您执行函数createMapping
时,输出(ret
)应该是MyInterface
类型。