You should remove explicit T return type from get scale(): T.
Because during initialization, T inferes as literal type of argument.
COnsider this example:
class Scaling<T extends string> {
_scale = "";
constructor(props: T) {
this._scale = props;
}
setScale(scale: T) {
this._scale = scale;
}
get scale(): T {
return this._scale;
}
}
// T infered as literal "hello"
const result = new Scaling('hello')
Hence, when you want to return T it should be "hello".
In your example, it can't be "hello" because default value of _scale is empty string and accordingly it is infered as a string.
let str = ''
// Type 'string' is not assignable to type '"hello"'
const sameCase = (): 'hello' => str
You can't use T as an explicit type for _scale because _scale is mutable and types are immutable.
This is why it is unsafe to return T type from get scale
Even if i remove the T from the get scale, i still get an error when for const result = new Scaling("hello"); result.setScale("other")
My bad, did not check it.
In order to make this class generic we need to convert infered T from more specific type to more wider.
type Infer<T> = T extends infer R ? R : never
class Scaling<T extends string> {
_scale = "";
constructor(props: Infer<T>) {
this._scale = props;
}
setScale(scale: T) {
this._scale = scale;
}
get scale() {
return this._scale;
}
}
// T infered as literal "hello"
const result = new Scaling('hello') // ok
result.setScale('123') // ok
Playground