Convert interface to enum (for those too lazy to type 'name' in the input form) in TypeScript
- Nook Ittipon
- Programming , categories/programming Improvement categories/improvement
- 13 Nov, 2021
It’s a small trick to convert an Interface to an Enum, helping to solve cases where you hard code Property Name Strings using JavaScript’s Proxy API.
In this article, the author provides examples and code samples at the beginning of the article. Then, they proceed to discuss the benefits/limitations and conclude with an explanation of the code.
Have you ever encountered these problems?
- Being lazy to type the ‘name’ of an input (or maybe ‘title,’ ‘value,’ etc., depending on the framework).
- Data not showing up because the ‘name’ was typed incorrectly (and it doesn’t raise an error).
- Bugs occur when the property of an Interface gets renamed, but the corresponding input’s name is forgotten to be changed (and no error is raised either).
I am proud to present…
const interfaceToEnum = <T>() => {
return new Proxy(
{},
{
get: function (target, prop, receiver) {
return prop
},
},
) as {
[P in keyof T]-?: P
}
}
export default interfaceToEnum
How to use it
How to declare
const ProfileProperty = interfaceToEnum<IProfile>()
How to use it in Form
Let me explain the example above. We have an Interface called ‘Profile
interface IProfile {
firstName: string
lastName: string
age: number
}
There is a Profile Form (old version) that requires hard coding the names of inputs.
<form>
<input name={"firstName"} />
<input name={"lastName"} />
<input name={"age"} />
</form>
If there are more than 3 properties, or even more than 10, I would be too lazy to type them all out or might make mistakes again. In such cases, I can use this method to solve the issue.
const ProfileProperty = interfaceToEnum<IProfile>()
function ProfileForm() {
return (
<form>
<input name={ProfileProperty.firstName} />
<input name={ProfileProperty.lastName} />
<input name={ProfileProperty.age} />
</form>
);
}
export default ProfileForm
EZ Game EZ Life
If you like it, the author is happy to share.
If you don’t like it, you can criticize, but please don’t be too harsh on the writer; they are still learning.
Also, if anyone has a better method to share, feel free to do so, but there’s no need to pay for it.
Advantages:
- It helps guide our code editing by automatically suggesting tabs after typing 2-3 characters.
- It reduces typos when writing ‘name.‘
- It minimizes the occurrence of bugs when Interface Property Names are changed, but the corresponding input names are forgotten to be updated.
These are the only advantages that come to mind.
Limitations:
- It seems to be limited to only one level of inheritance; it cannot inherit from a grandparent or great-grandparent (this can be solved by declaring a new one as belonging to the grandparent).
- It appears that the Proxy might not be compatible with older IE browsers (not sure if there are any polyfills to address this).
- There are many other limitations, but I’m too hesitant to write them down, feeling embarrassed.
Our Proxy: Proxy is a basic JavaScript API that helps modify the behavior of original objects. If confused, read and see more examples from the link below because that’s all I know.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#description
Based on the original code:
const interfaceToEnum = <T>() => {
return new Proxy(
{},
{
get: function (target, prop, receiver) {
return prop
},
},
) as {
[P in keyof T]-?: P
}
}
export default interfaceToEnum
Let me explain the provided text step by step:
get: function (target, prop, receiver): This is an API of the Proxy. It helps transform the value that will be returned. In this case, only the prop is used, and the other two parameters are not utilized.
as { [P in keyof T]-?: P }: Let’s break this down:
- as: This indicates the type cast, specifying what the return type should be.
- { [P in keyof T]-?: P }: This constructs a new type that iterates over each property P in the keys of T.
- The -? part means that optional properties will be removed (e.g., name? and age? will become name and age). The result is a new type with the format [objectName]: propertyName, like firstName: “firstName”.
To summarize: The provided code seems to be a demonstration of using Generic Types in TypeScript to cast a given object type and make it reusable. It also involves using the get function of the Proxy API to modify the returned value. The last part contains an explanation of how the type cast works, using the as keyword and iterating through the properties of the given object type.
Finished! Thank you very much :D