I have different data structures as follows
type X = {
apple: number
orange: number
}
type Y = {
apple: string
orange: string
}
My goal is to create a function convert()
that takes input which could be completely or partially of type X, and generates an object with corresponding keys, but the types are from type Y.
For instance,
convert(x) = {apple: 1, orange: 2}
// the return should be {apple: string, orange: string}
convert(x) = {apple: 1}
// the return should be {apple: string}
convert(x) = {orange: 1}
// the return should be {orange: string}
I attempted to use generics, however, due to Typescript's lack of checking for excess properties, I encounter an error when utilizing keyof
:
function convert<T extends X>(input: T): {[K in keyof T]: Y[K]} {
// Type 'K' cannot be used to index type 'Y' ^^^^^
// ... implementation goes here
}
To make this approach viable, I need to somehow constrain T
to only represent a subset of type X
, though finding a solution that clarifies to the compiler that keyof T
can actually index X
has proven futile.
The closest attempt involves utilizing Partial
, but it does not match the desired functionality:
function convert(input: Partial<X>): Partial<Y> {
// pseudo code here, output details are insignificant, focus on types
const result: Partial<Y> = {};
let key: keyof typeof input;
for (key in input) {
const value = input[key];
result[key] = parseInt(value ?? "0");
}
return result;
}
This method is flawed because all the given inputs produce outputs of identical types:
const x = convert({})
const y = convert({apple: 1})
const z = convert({orange: 2})
// x, y, z all share type {apple?: number, orange?: number)
// expected behavior:
// x: {}
// y: {apple: string}
// z: {orange: string}
Is the sought-after solution achievable in current Typescript? Any insights or workarounds would be greatly appreciated.