简体   繁体   中英

How do I use a reference to a property in an interface as a type in TypeScript?

In this app I'm writing, there's an interface that controls the settings; here's an example of what it may look like:

export interface Config {
  volume: number
  graphics: string
  darkMode: boolean
}

Which I then have a class that implements it that looks like this:

import {Config} from './config'

export class DefaultConfig implements Config {
  volume = 100
  graphics = 'low' // I'd usually use an enum for this, but this is just an example
  darkMode = false
}

Which finally get loaded into a Settings class that looks like this:

import {DefaultConfig} from './default-config'

export abstract class Settings {
  static config = new DefaultConfig()
}

So, the issue is that I want the user to be able to change, for example, the volume using an HTML range input element. The question I want to know the answer to is: how can I specify a type where it has to be a property of a class that has a type of number? For example:

import {Settings} from './settings'
import {HtmlUiElement} from './html-ui-element'

export class HtmlSettingSlider extends HtmlUiElement {
  protected setting: number // What type can I put here instead?
  // Code to assign, change, read from the setting goes here
}

I want to assign to the setting property, for example: Settings.config.volume

While 'number' technically works, it's not type protected; I want it to be a requirement that it's a value of Config with the type number. Is this possible to do?

You probably mean to do this

export class HtmlSettingSlider implements HtmlUiElement {
    protected setting: Config[keyof Config] & number
}

Now I'm completely lost with all of your classes. I think you overcomplicate things and I would advise you to use plain old Javascript objects when possible like so.

const defaultConfig: Config = {
    volume: 100,
    graphics: 'low', 
    darkMode:false
};

But I'm probably missing something

That will only work if you define a different interface for each variable inside Settings. Something like this.

export interface Volume {
    value: boolean;
}

export interface Graphics {
    value: string;
}

export interface DarkMode { value: boolean; }

export interface Config {
    volume: Volume;
    graphics: Graphics;
    darkMode: DarkMode;

}

Now you're safe and can control which Type of value to go in. Then you can say:

setting: Volume = Settings.config.volume;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM