I have single interface one is mostly all kind of types, but i want to use the same interface, again but with all types as “strings”. how to do it without writing the types twice?
Thanks
interface #1
interface formValuesState {
ownerType: string,
platformUrl?: string,
serviceUrl?: string,
fullName: string,
email: string,
password1: string,
password2: string,
agreeTermsCheckbox: string,
}
interface #2
interface formValuesState {
ownerType: boolean,
platformUrl?: string,
serviceUrl?: string,
fullName: string,
email: string,
password1: string,
password2: string,
agreeTermsCheckbox: boolean,
}
how do i use the same one without writing it twice?
objects as example:
const data = {
ownerType: true,
platformUrl?: 'test',
serviceUrl?: 'test',
fullName: 'test',
email: 'test',
password1: 'test',
password2: 'test',
agreeTermsCheckbox: false,
}
// data 2:
const data = {
ownerType: 'test now as string',
platformUrl?: 'test',
serviceUrl?: 'test',
fullName: 'test',
email: 'test',
password1: 'test',
password2: 'test',
agreeTermsCheckbox: 'now as string',
}
Thanks for the help!
The best way i could think of is to use omit
interface formErrorsState extends Omit<formValuesState, 'ownerType' | 'agreeTermsCheckbox'> {
ownerType: string,
agreeTermsCheckbox: string
}
but i am not a big fan, it’s a bit odd, maybe there’s a better more “typescript approach.
Turing Vang is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
In this scenario one can use Unions defined by the pipe character |
.
You can read it like X or Y. e.g: string | boolean
reads string or boolean
interface formValuesState {
ownerType: string | boolean,
platformUrl?: string,
serviceUrl?: string,
fullName: string,
email: string,
password1: string,
password2: string,
agreeTermsCheckbox: string | boolean,
}
Then use it
const data: formValuesState = {
ownerType: "string", // OK
...
}
const data2: formValuesState = {
ownerType: true, // OK
...
}
Given one type:
interface FormValuesState {
ownerType: boolean,
platformUrl?: string,
serviceUrl?: string,
fullName: string,
email: string,
password1: string,
password2: string,
agreeTermsCheckbox: boolean,
}
you can use a mapped type to derive the other:
type FormValuesStateAsString = {[K in keyof FormValuesState]: string}
alternatively, you could use the utility type Record
:
type FormValuesStateAsString = Record<keyof FormValuesState, string>;
The two solutions differ in how they handle optional properties: The mapped type keeps the optional keys optional, while the Record
makes them mandatory.
If you need this in many places, you can use a generic type to reuse the derivation rule:
type StringValues<T extends object> = {[K in keyof T]: string};
const state: StringValues<FormValuesState> = ...
const otherState: StringValues<OtherFormValuesState> = ...