[英]Typescript: Problem with generic Parameter/ReturnType and string Enums
I currently try to add proper typings to the following simplified function:我目前尝试为以下简化的 function 添加正确的类型:
getProperty(property:string):any
My goal is to make it possible to pass the property parameter as string
or string enum
and get the correct return type for it.我的目标是能够将属性参数作为
string
或string enum
传递,并为其获取正确的返回类型。
For that I have created a new string enum
Property:为此,我创建了一个新的
string enum
属性:
enum Property {
ENABLED = 'enabled',
SIZE = 'size'
}
a generic type
PropertyType: generic type
PropertyType:
type PropertyType < T > =
T extends Property.ENABLED ? boolean :
T extends Property.SIZE ? number : any;
and changed the function signature to:并将 function 签名更改为:
getProperty<T extends Property>(property : T) : PropertyType<T>
This works perfect if I call the function with the new string enum
:如果我用新的
string enum
调用 function ,这将非常有效:
const enabled: boolean = getProperty(Property.ENABLED);
But if I call the function with a simple string (needed for backward compatibility) like that:但是,如果我用一个简单的字符串(向后兼容所需)调用 function,如下所示:
const enabled: boolean = getProperty("enabled");
I get the following error:我收到以下错误:
Argument of type '"enabled"' is not assignable to parameter of type 'Property'.(2345)
Is there any good way to support both ways ( string
& string enum
) to pass the property parameter?有没有什么好方法可以支持两种方式(
string
和string enum
)来传递属性参数?
My example is also available here: Typescript Playground我的例子也可以在这里找到: Typescript Playground
You can either overload the function or make the type parameter of getProperty
a union type.您可以重载function 或将
getProperty
的类型参数设置为联合类型。
Overload:超载:
function getProperty(property: string): any;
function getProperty<T extends Property>(property : T) : PropertyType<T>
{
return store[property];
}
Union Type:工会类型:
function getProperty<T extends Property | string>(property : T) : PropertyType<T>
{
return store[property];
}
Full code:完整代码:
//Example Value store
const store: { [key: string]: any } = {
"enabled": true,
"size": 4
};
//--------------------------------------------------------------------------
//String Enum Property
enum Property {
ENABLED = 'enabled',
SIZE = 'size'
}
//--------------------------------------------------------------------------
//Property Types
type PropertyType < T > =
T extends Property.ENABLED ? boolean :
T extends Property.SIZE ? number : any;
//--------------------------------------------------------------------------
// Generic getProperty function
function getProperty<T extends Property | string>(property : T) : PropertyType<T>
{
return store[property];
}
//--------------------------------------------------------------------------
const enabled0: boolean = getProperty(Property.ENABLED);
const enabled1: boolean = getProperty('enabled');
Another way is to just simply choose a different function name, since you don't gain any type safety from overloading.另一种方法是简单地选择一个不同的 function 名称,因为您不会从重载中获得任何类型安全。 Imo this is a better option to stay backwards compatible.
Imo 这是保持向后兼容的更好选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.