I currently try to add proper typings to the following simplified 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.
For that I have created a new string enum
Property:
enum Property {
ENABLED = 'enabled',
SIZE = 'size'
}
a generic type
PropertyType:
type PropertyType < T > =
T extends Property.ENABLED ? boolean :
T extends Property.SIZE ? number : any;
and changed the function signature to:
getProperty<T extends Property>(property : T) : PropertyType<T>
This works perfect if I call the function with the new string enum
:
const enabled: boolean = getProperty(Property.ENABLED);
But if I call the function with a simple string (needed for backward compatibility) like that:
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?
My example is also available here: Typescript Playground
You can either overload the function or make the type parameter of getProperty
a union type.
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. Imo this is a better option to stay backwards compatible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.