在下面的代碼中,如果我使用T extends HealthyConfig并使用泛型創建Config類實體,T則會出現錯誤Type 'boolean' does not satisfy the constraint 'T[keyof T]',但直接參考時HealthyConfig不會顯示錯誤。當然,因為TextendsHealthyConfig型別至少應該是已知的,HealthyConfig所以為什么它不能與 using 一起使用T?
type Key = string | number;
type Val = Key | boolean | Obj;
type Obj = { [x: Key]: Val } | Array<Val>;
interface Config<T extends Obj> {
get<Tret extends T[keyof T]>(key: keyof T, defaultVal: Tret): Tret;
}
type EnabledConfig = {
enabled?: boolean;
}
class Enabled<T extends EnabledConfig> implements Config<T> {
public readonly c: T;
constructor(c?: T) {
this.c = c || {} as T;
}
get<Tret extends T[keyof T]>(key: keyof T, defaultVal: Tret): Tret {
const result: Tret = this.c[key] as Tret;
return (result === undefined) ? defaultVal : result;
}
}
type Status = 'yes' | 'no';
type HealthyConfig = EnabledConfig & {
healthy?: Status;
}
class Healthy {
public readonly config: Config<HealthyConfig>
constructor(config: Config<HealthyConfig>) {
this.config = config;
}
get enabled(): boolean {
return this.config.get<boolean>('enabled', true);
}
}
const en = new Enabled<HealthyConfig>({enabled: false});
const isEnabled: boolean = en.get<boolean>('enabled', true); // works
const isHealthy: Status = en.get<Status>('healthy', 'no'); // works
const h = new Healthy(new Enabled<HealthyConfig>({enabled: true, healthy: 'no'}));
const enabled: boolean = h.config.get<boolean>('enabled', true); // works
const healthy: Status = h.config.get<Status>('healthy', 'yes'); // works
// This generic "T extends HealthyConfig" causes a problem
// with the "this.config.get" showing an error on the "<boolean>"
// of "Type 'boolean' does not satisfy the constraint 'T[keyof T]'"
class UnHealthy<T extends HealthyConfig> {
public readonly config: Config<T>
constructor(config: Config<T>) {
this.config = config;
}
get enabled(): boolean {
return this.config.get<boolean>('enabled', true);
}
}
uj5u.com熱心網友回復:
我對您的代碼進行了一些重構:
type Key = string | number;
type Val = Key | boolean | Obj;
type Obj = { [x: Key]: Val } | Array<Val>;
interface Config<T extends Obj> {
get<K extends keyof T, V extends T[K]>(key: K, defaultVal: V): V;
}
type EnabledConfig = {
enabled?: boolean;
}
class Enabled<T extends EnabledConfig> implements Config<T> {
public readonly c: T;
constructor(c?: T) {
this.c = c || {} as T;
}
get<K extends keyof T, V extends T[K]>(key: K, defaultVal: V): V {
const result: V = this.c[key] as V;
return (result === undefined) ? defaultVal : result;
}
}
type Status = 'yes' | 'no';
type HealthyConfig = EnabledConfig & {
healthy?: Status;
}
class Healthy {
public readonly config: Config<HealthyConfig>
constructor(config: Config<HealthyConfig>) {
this.config = config;
}
get enabled() {
return this.config.get('enabled', true);
}
}
const en = new Enabled<HealthyConfig>({enabled: false});
const isEnabled: boolean = en.get('enabled', true); // works
const isHealthy: Status = en.get('healthy', 'no'); // works
const h = new Healthy(new Enabled<HealthyConfig>({enabled: true, healthy: 'no'}));
const enabled: boolean = h.config.get('enabled', true); // works
const healthy: Status = h.config.get('healthy', 'yes'); // works
// This generic "T extends HealthyConfig" causes a problem
// with the "this.config.get" showing an error on the "<boolean>"
// of "Type 'boolean' does not satisfy the constraint 'T[keyof T]'"
class UnHealthy<T extends Config<HealthyConfig>> {
public readonly config: T
constructor(config: T) {
this.config = config;
}
get enabled() {
return this.config.get('enabled', true);
}
}
這是你需要的嗎?
uj5u.com熱心網友回復:
為什么你需要 UnHealthy 是通用的?提供具體配置,HealthyConfig 在您的情況下,編譯器將選擇 T[keyof T],并且您將無法使用不同于boolean | Status | undefineddefaultVal arg 的型別。
class UnHealthy {
public readonly config: Config<HealthyConfig>
constructor(config: Config<HealthyConfig>) {
this.config = config;
}
get enabled() {
console.log(this.config)
return this.config.get('enabled', false)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/494521.html
