Typescript 如何将固定类型值指定给泛型约束类型的分部?
我有一个基本的接口,用于可能有ID的东西:Typescript 如何将固定类型值指定给泛型约束类型的分部?,typescript,Typescript,我有一个基本的接口,用于可能有ID的东西: 接口可识别{ id?:编号; } 我有一个通用函数,可以将记录对象转换为id为的对象: 函数fromRowToObj1(行:{id:number;}):部分{ 返回{id:row.id}; //类型“{id:number;}”不可分配给类型“Partial”。 } 我知道发生这种情况是因为有Ts扩展了identificatable,这将使返回语句非法。例如,类型{id:undefined}或{id:1}。因此,我决定稍微调整返回类型以强制使用数字i
接口可识别{
id?:编号;
}
我有一个通用函数,可以将记录对象转换为id为的对象:
函数fromRowToObj1(行:{id:number;}):部分{
返回{id:row.id};
//类型“{id:number;}”不可分配给类型“Partial”。
}
我知道发生这种情况是因为有T
s扩展了identificatable
,这将使返回语句非法。例如,类型{id:undefined}
或{id:1}
。因此,我决定稍微调整返回类型以强制使用数字id:
识别的类型={
[K in keyof T]?:K扩展“id”?编号:T[K];
}
//应该给出类似类型C={id?:number | undefined;…}
函数fromRowToObj2(行:{id:number;}):已标识{
返回{id:row.id};
//类型“{id:number;}”不可分配给类型“Identified”。
}
为什么呢?哪个可能的T
(这样T扩展了可识别的)使得{id:number}
不可分配给已识别的
如果无法调整已识别的
类型以使其正常工作,是否有其他方法键入转换函数以处理可识别的
的泛型子类型
.您所面临的问题已被详细描述。正如您自己所注意到的,T扩展可识别的
的子类型使得您的返回值{id:row.id}
无效。例如,Identified
将永远不会对{id:row.id}
有效Never
仍然是id
的有效类型,因为您已将标识的所有键声明为可选<如果T扩展了可识别的
,则code>Identified实际上等于Partial
。Typescript在此正确抛出错误。但是,如果您设置了有效的默认值,您仍然可以解决这个问题,您可以从该值开始工作():
接口可识别{
id?:编号;
}
//结果为可选id
函数fromRowToObj1(行:{id:number;}){
const result:Partial={}//对Partial的所有子类型有效
result.id=row.id
返回结果;
}
//结果为非可选id
函数fromRowToObj2(行:{id:number;}){
const partial:partial={};//对partial的所有子类型有效
常数结果={
部分的
id:row.id
};
返回结果;
}
接口测试对象{
身份证号码:,
arg1:字符串;
arg2:布尔型;
}
const result1=fromRowToObj1({id:5});
result1.id//可选
result1.arg1=“测试”//intellisense工作正常
result1.arg2=true;//智能感知工作
const result2=fromRowToObj2({id:5});
result2.id//非可选
result2.arg1=“测试”//intellisense有效
result2.arg2=true;//智能感知工作
只要可识别的id是可选的,这些解决方案就有可能破坏它们的类型。我在操场上贴了一个这样的例子。但是这些类型可能无论如何都不会被使用。游乐场说,可识别的
是{id?:number |未定义的}
。那么为什么不能将{id:number}
分配给它呢?不管怎样,您的第二个非可选id的示例非常有效。有了它,我可以将返回类型键入Partial&{id:number}
,这正是我想要的。我真的觉得有点奇怪,不得不经历这样的困境。
interface Identifiable {
id?: number;
}
// results in optional id
function fromRowToObj1<T extends Identifiable>(row: { id: number; }) {
const result: Partial<T> = {} // valid for all subtypes of Partial<T>
result.id = row.id
return result;
}
// results in non optional id
function fromRowToObj2<T extends Identifiable>(row: { id: number; } ) {
const partial: Partial<T> = {}; // valid for all subtypes of Partial<T>
const result = {
...partial,
id: row.id
};
return result;
}
interface TestObject {
id: number,
arg1: string;
arg2: boolean;
}
const result1 = fromRowToObj1<TestObject>({id: 5});
result1.id // optional
result1.arg1 = "test" // intellisense works
result1.arg2 = true; // intellisense works
const result2 = fromRowToObj2<TestObject>({id: 5});
result2.id // not optional
result2.arg1 = "test" // intellisense works
result2.arg2 = true; // intellisense works