Hi,
I'd like to express the following purely on type level (= no implementation):
"a class Foo has property x. When you read x, you will always get a string. But you can put both a string or a number into x"
I know that I can solve this on implementation level with getters and setters:
class Foo {
get x(): string { return '' }
set x(x: number | string) {}
}
const foo = new Foo()
foo.x = 42
foo.x = '42'
const fooString: string = foo.x
but this means I have to provide a (stub) implementation for the getter and setter, as they can not be declared, and I have to do this for every property of this kind.
I would prefer something like
type Magic<P, R> = { set (x: P), get: R }
class Foo {
x: Magic<number | string, string>
y: Magic<number | string, string>
z: Magic<number | string, string>
}
But I have not found anything like that so far.
I tried indexed access types, but that only seems to "copy" the getter:
class Bar {
declare y: Foo['x']
}
const bar = new Bar()
bar.y = 42 // Type 'number' is not assignable to type 'string'.(2322)
bar.y = '42'
const barString: string = bar.y
any advice is welcome.