I can't figure out a way to discard readonly props when mapping a type to another.
type SimplePOJO = {
first_name: string;
readonly last_name: string;
year: number;
}
type Mapper<T extends SimplePOJO> = {
[K in keyof T]: { name: K, type: T[K] }
}
// I also tried this without any luck:
//
// type Mapper<T extends SimplePOJO> = {
// [K in keyof T]: T[K] extends Readonly<T[K]> ? never : { name: K, type: T[K] }
// }
type MappedPOJO = Mapper<SimplePOJO>
{
first_name: {
name: "first_name";
type: string;
};
year: {
name: "year";
type: number;
};
}
{
first_name: {
name: "first_name";
type: string;
};
readonly last_name: {
name: "last_name";
type: string;
};
year: {
name: "year";
type: number;
};
}
Is this possible with TypeScript?
There is a way to identify the writable keys and only keep them.
Example in the following snippet
type SimplePOJO = {
first_name: string;
readonly last_name: string;
year: number;
}
type IfEquals<X, Y, A=X, B=never> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? A : B;
type WritableKeys<T> = {
[P in keyof T]-?: IfEquals<{
[Q in P]: T[P];
}, {
-readonly [Q in P]: T[P];
}, P>
}[keyof T];
type Mapper<T extends SimplePOJO> = Pick<{
[K in keyof T]: {
name: K;
type: T[K];
};
}, WritableKeys<T>>;
type MappedPOJO = Mapper<SimplePOJO>;
Look at @jcalz explaination for the IfEquals
and WritableKeys
A simpler solution could be for you to specify the key to remove :
type SimplePOJO = {
first_name: string;
readonly last_name: string;
year: number;
}
type Mapper<T extends SimplePOJO> = Omit<{
[K in keyof T]: {
name: K;
type: T[K];
};
}, 'last_name'>;
type MappedPOJO = Mapper<SimplePOJO>;