I'm creating a generic class named Loadable<T>
, with two fields. One is named state
, and contains the current state of the loadable resource. The second is named data
, and contains the value of the loadable resource.
state
is defined as "loading" | "loaded" | "error"
, and I'd like to type of data
to change based on the current value of state
.
For example, if state
is "loading"
, then data
should be null
. I cannot figure out the syntax to do this.
I've created a type
named LoadableState<T, U>
which is defined as:
type LoadableState<T, U> =
T extends "loaded" ? U :
T extends "loading" ? null :
T extends "error" ? string :
never;
Where T
passed must be the type "loaded" | "loading" | "error"
.
This part works, but trying to define data
from this does not.
export class Loadable<T> {
public state: "loaded" | "loading" | "error" = "loading";
public data: LoadableState<state, T>;
// ^^^^^ Cannot find name 'state`
}
TypeScript throws the following error: Cannot find name 'state'
Other things I've tried:
public data: LoadableState<this.state, T>;
// Duplicate identified 'state'
public data: LoadableState<typeof this.state, T>;
// Cannot find name 'this'
public data: LoadableState<typeof state, T>;
// Cannot find name 'state'
public data: state extends "loaded" ? T :
state extends "loading" ? null :
state extends "error" ? string :
never;
// Cannot find name 'state'
I'm not sure if this is actual possible. If this isn't, is there another solution to this problem?