I want to define an interface for my classes that contains a isValidConfig
function to be used as type guard. But I am not sure how to declare it.
I have done this:
type AnyConfig = ConfigA | ConfigB | ConfigC;
public abstract isValidConfig<T extends AnyConfig>(config: AnyConfig): config is T;
and
public abstract isValidConfig<T = AnyConfig>(config: T): config is T;
But I always get errors in the implementation like:
public isValidConfig<T extends ConfigA >(config: T): config is T {
return config.type === TrainingTypes.A;
} /// Types of parameters 'config' and 'config' are incompatible.
Type 'T' is not assignable to type 'ConfigA '.
Is it possible to do this? I haven't found the way.
Wouldn't it be easier to use instanceof type guards? https://www.typescriptlang.org/docs/handbook/advanced-types.html#instanceof-type-guards
The error is because you can't have have a guard that enforce against a generic. Following from the official TS docs: https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
You can do something like this to guard against an individual type:
enum ConfigTypes {
a = 'a',
b = 'b',
c = 'c'
}
interface ConfigA {
field: number;
type: ConfigTypes.a;
}
interface ConfigB {
otherField: string;
type: ConfigTypes.b;
}
interface ConfigC {
yetAnotherField: string[];
type: ConfigTypes.c;
}
type AnyConfig = ConfigA | ConfigB | ConfigC;
export function isValidConfigA(config: AnyConfig): config is ConfigA {
return config.type === ConfigTypes.a;
}
It's worth adding that types must be enforced at compile time because TypeScript simply cannot perform run-time checks (by then it's already been transpiled to JavaScript, which performs dynamic (run-time) checking). In other words, you can only guard against a specific known type.
If you want to check that a given expected config IS a config, then continuing from the example above, you can do:
export function isValidConfig(config: AnyConfig): config is AnyConfig {
return (
config.type === ConfigTypes.a ||
config.type === ConfigTypes.b ||
config.type === ConfigTypes.c
);
}
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.