In Options<T>
as you want it to return an object with the parameter isSuper
or notSuper
I added in an interface for both of them.
interface IisSuper { isSuper: boolean }
interface InotSuper { notSuper: boolean }
In Options<T>
as it can either be one of the aforementioned interfaces I created a union type for it called TSuper
.
type Options<T> = T extends Super ? IisSuper : InotSuper
type TSuper = IisSuper | InotSuper
In the function withOptions<T>
I used the as
keyword, which is a Type Assertion which tells the compiler to consider the object as another type than the type the compiler infers the object to be. In this case it is the union of both IisSuper
and InotSuper
which Options<T>
can exist as.
As Typescript cannot guarantee the type of options
at runtime as you want to access either notSuper
or isSuper
so you have to narrow down the scope using the in
keyword for options
to access the parameter in the type you want.
function withOptions <T>(makeOptions: MakeOptions): void {
const options = makeOptions<T>() as TSuper;
if('notSuper' in options){
console.log(options.notSuper);
}
else if('isSuper' in options){
console.log(options.isSuper);
}
}
Final code:
interface Base { basic: boolean };
interface Super { basic: boolean; extra: boolean };
interface IisSuper { isSuper: boolean }
interface InotSuper { notSuper: boolean }
type Options<T> = T extends Super ? IisSuper : InotSuper
type MakeOptions = <T>() => Options<T>
type TSuper = IisSuper | InotSuper
const baseOptions: Options<{ basic: boolean }> = { notSuper: true };
const superOptions: Options<{ basic: boolean; extra: boolean }> = { isSuper: true };
function withOptions <T>(makeOptions: MakeOptions): void {
const options = makeOptions<T>() as TSuper;
if('notSuper' in options){
console.log(options.notSuper);
}
else if('isSuper' in options){
console.log(options.isSuper);
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…