[英]TypeScript: function that returns a generic Type which extends Record<string, string>
I want to create a parse<Type>()
function that parses a string and returns an object, but I want parse()
to return the correct type, and I am struggling.我想创建一个解析字符串并返回 object 的
parse<Type>()
function,但我希望parse()
返回正确的类型,而我正在苦苦挣扎。
type Identity = {
name: string;
};
type ContactDetails = {
phone: string;
email: string;
};
function parse<T extends Record<string, string>>(input: string): T {
const result = {};
input.split('&').forEach(bits => {
const [name, value] = bits.split('=');
result[name] = value;
});
return result;
}
parse<Identity>('name=Paulin');
parse<ContactDetails>('phone=0123456789&email=paulin@email.com');
I get a TypeScript error:我收到 TypeScript 错误:
Type '{}' is not assignable to type 'T'.
类型“{}”不可分配给类型“T”。 '{}' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Record'.ts(2322)
“{}”可分配给“T”类型的约束,但“T”可以用约束“记录”的不同子类型实例化。ts(2322)
I understand what the problem is: {}
is not compatible with a generic Record
type.我了解问题所在:
{}
与通用Record
类型不兼容。 But how can I solve this?但是我该如何解决呢?
Thank you very much!非常感谢!
I'm fairly sure this is one of the places you have to resort to a type assertion.我相当确定这是您必须诉诸类型断言的地方之一。 In this case:
在这种情况下:
function parse<T extends Record<string, string>>(input: string): T {
const result: Record<string, string> = {};
// −−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^
input.split('&').forEach(bits => {
const [name, value] = bits.split('=');
result[name] = value;
});
return result as T;
// −−−−−−−−−−−−^^^^^
}
It's important to understand the limitations here, though.不过,了解这里的限制很重要。 If your
Identity
or ContactDetails
types had specific implementations (they don't in your example, they're just interface
s), the object parse
returns won't be backed by that implementation.如果您的
Identity
或ContactDetails
类型具有特定的实现(在您的示例中它们没有,它们只是interface
),则 object parse
返回将不受该实现的支持。 It is just a Record<string, string>
.它只是一个
Record<string, string>
。 So you might be better off having parse
return a Record<string, string>
instead, and leave it to the caller to make an informed decision about the type.因此,您最好让
parse
返回Record<string, string>
,并将其留给调用者以对类型做出明智的决定。
Based on what TJ Crowder suggested: leave it to the caller to make the decision about the type.根据 TJ Crowder 的建议:让调用者决定类型。 here is my final implementation:
这是我的最终实现:
type Identity = {
name: string;
};
type ContactDetails = {
phone: string;
email: string;
};
function parse(input: string): Record<string, string> {
const result: Record<string, string> = {};
input.split('&').forEach(bits => {
const [name, value] = bits.split('=');
result[name] = value;
});
return result;
}
const identity = parse('name=Paulin') as Identity;
const details = parse('phone=0123456789&email=paulin@email.com') as ContactDetails;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.