Issue
The following is a simplified scenario.
I want to define a function swap
whose job is very simple. If the input is Foo
, then swap the fields and output Bar
. And the other way around.
I can't find a good way to define this function's type. May you help? Thanks.
type FooBar = Foo | Bar;
type Foo = { a: string; b: number };
type Bar = { a: number; b: string };
// function swap({ a, b }: Foo): Bar;
// function swap({ a, b }: Bar): Foo;
function swap({ a, b }: FooBar): FooBar {
return { a: b, b: a };
}
I don't want to do this because I want to avoid code repetition.
function isFoo(x: FooBar) : x is Foo{
return typeof x.a === 'string';
}
function swap(x: FooBar): FooBar {
if (isFoo(x)) {
const {a,b} = x;
return {a: b, b: a}
}
const {a,b} = x;
return {a: b, b: a}
}
Solution
To avoid code repetition and have a single swap function, you can use generics and conditional types in TypeScript. Here's how you can achieve this:
type FooBar = Foo | Bar;
type Foo = { a: string; b: number };
type Bar = { a: number; b: string };
function swap<T extends FooBar>(obj: T): T extends Foo ? Bar : Foo {
const { a, b } = obj;
return { a: b, b: a } as T extends Foo ? Bar : Foo;
}
// Test cases
const foo: Foo = { a: "hello", b: 42 };
const bar: Bar = { a: 42, b: "world" };
const swappedFoo = swap(foo); // should be of type Bar
const swappedBar = swap(bar); // should be of type Foo
console.log(swappedFoo); // Output: { a: 42, b: "hello" }
console.log(swappedBar); // Output: { a: "world", b: 42 }
This implementation of the swap function utilizes a generic type T that extends FooBar. Then, it uses a conditional type to determine whether the input obj is of type Foo or Bar, and based on that, it swaps the fields accordingly and returns the appropriate type.
Answered By - IPS Brar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.