我不太确定在哪里objectA
来自,但你可以得到你想要的。首先,无论在哪里objectA
来自,你应该让 TypeScript 知道这些值是特定的字符串文字类型 https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types。有不同的方式 https://stackoverflow.com/a/47613767/2887218去做这个。最直接(但不是 DRY)的方法是使用类型断言:
interface MyInterface {
a: string
b: string
}
const objectA = {
a: "val1" as "val1",
b: "val2" as "val2"
}
注意objectA
没有被注释为MyInterface
,因为您不希望 TypeScript 忘记它的属性是"val1"
and "val2"
。它的兼容性MyInterface
稍后将进行验证。
现在我们可以创建一个可以接受任何内容的函数MyInterface
-like(具有字符串属性)并生成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;
}
The O
参数是你的类型MyInterface
目的。我们打电话吧makeCreateMapping()
with objectA
:
const createMapping = makeCreateMapping(objectA);
这就是事实所在objectA
is a MyInterface
如果没有的话,编译器就会对你大喊大叫。现在如果你检查的类型createMapping
, it is:
const createMapping: (response: ("a" | "b")[]) => Partial<Record<"val1" | "val2", true>>
也就是说,一个函数需要一个数组"a"
or "b"
,并返回一个Partial<Record<"val1" | "val2", true>>
这本质上是{val1?: true, val2?: true}
其有效值包括{val1: true}
, {val2: true}
, and {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
希望有帮助。祝你好运!