Typescript 键入静态对象的值,同时保持其键类型不变

Typescript 键入静态对象的值,同时保持其键类型不变,typescript,Typescript,假设我有以下接口和对象: 接口人{ 名称:字符串; lastName?:字符串; } 常量对象:{[key:string]:Person}={ 答:{姓名:'约翰'}, b:{name:'Jane',lastName:'Doe'}, } 这定义了对象的类型,使得其键可以是任何字符串。但是我仍然希望能够推断出对象的关键点(因为它是静态的),在这种情况下,我不能 我可以这样做: type ObjKeys='a'|'b'; const obj:{[key in ObjKeys]:Person}/。。

假设我有以下接口和对象:

接口人{
名称:字符串;
lastName?:字符串;
}
常量对象:{[key:string]:Person}={
答:{姓名:'约翰'},
b:{name:'Jane',lastName:'Doe'},
}
这定义了对象的类型,使得其键可以是任何
字符串。但是我仍然希望能够推断出对象的关键点(因为它是静态的),在这种情况下,我不能

我可以这样做:

type ObjKeys='a'|'b';
const obj:{[key in ObjKeys]:Person}/。。。
但这是冗长的


是否有一个简短的说法“这是该对象所有值的类型,但保留静态定义的键?”

您不能仅在类型级别执行此操作;如果使用
{[k:string]:Person}
指定
obj
的类型,编译器将假定这是要使用的实际类型,并且不会根据
{a:{…},b:{…}
的赋值将其指定给其他类型。只有类型为a且
{[k:string]:Person}
不是并集的值才会出现这种情况

在这种情况下,我通常会编写一个助手,编译器可以从中推断出您要查找的类型:

const asPersonDict = <K extends PropertyKey>(
  o: { [P in K]: Person }) => o;

要定义的对象的键在哪里?“我可以这样做”:这是无效的语法;在对象的定义过程中,您大概是指
{[K in ObjKeys]:Person}
。它是静态的,总是有键
a
b
@jcalz是的,你说得对。修好了,真的很酷。但为什么这样做有效?为什么不假设返回类型是
{[P in(string | number | symbol)]:Person}
?我试图理解它,因为我缺乏提出此解决方案所需的知识,我想知道我的知识中存在哪些差距。编译器在从对泛型函数的调用推断泛型类型参数时使用启发式。在类似于
K extensed PropertyKey
的情况下,其中
PropertyKey
string | number | symbol
的别名,它向编译器提示您希望它在可能的情况下推断
string
number
,而不是将其扩展为
string
number
;有关更多详细信息,请参阅。
const obj = asPersonDict({
  a: { name: 'John' },
  b: { name: 'Jane', lastName: 'Doe' },
});

/* const obj: {
    a: Person;
    b: Person;
} */