我正试图用一个方法创建一个类,该方法的返回类型将取决于标志参数的boolean
值
当
- 使用实现接口的普通函数表达式
- 或在类中声明方法时直接在类主体中重载
但是,当我试图使用类实现的接口时,我无法做到这一点。
我想使用类方法的接口实现来实现动态返回类型。
谢谢!
以下是Typescript Playground 中也可用的示例代码
// it works with interface for plain function
interface common {
<T extends boolean>(flag: T): T extends true ? string : boolean ;
(flag: boolean): string | boolean;
}
const method: common = (flag: boolean) => {
if (flag) {
return 'truhty';
} else {
return false ;
}
}
// it works with plain method overload
function test(flag: true): string
function test(flag: false): boolean
function test(flag: boolean): string | boolean {
if (flag) {
return 'truthy'
} else {
return false;
}
}
const x = test(true);
const y = test(false);
// This works with direct class method overload
class Exp {
test(flag: true): string
test(flag: false): boolean
test(flag: boolean): string | boolean {
if (flag) {
return 'truthy'
} else {
return false;
}
}
}
const val = new Exp().test(false); // boolean!
const val2 = new Exp().test(true); // string!
// It does not work in class with interface overload
interface common2 {
test(flag: true): string
test(flag: false): boolean
test(flag: boolean): string | boolean
}
class Exp2 implements common2 {
test(flag: boolean) {
if (flag) {
return 'truthy'
} else {
return false;
}
}
}
// it is not working in class with generic conditional type
interface common3 {
test<T extends boolean>(flag: T): T extends true ? string: boolean
test(flag: boolean): string | boolean
}
class Exp3 implements common3 {
test(flag: boolean) {
if (flag) {
return 'truthy';
} else {
return false;
}
}
}
const val3 = new Exp3().test(false); // WRONG false | 'truthy'!
const val4 = new Exp3().test(true); // WRONG false | 'truthy'!
// it does not work with conditional directly in class
class Exp4 {
test<T extends boolean>(flag: T): T extends true ? string : boolean
test(flag: boolean) {
if (flag) {
return 'truthy';
} else {
return false;
}
}
}
const val5 = new Exp3().test(false); // WRONG false | 'truthy'!
const val6 = new Exp3().test(true); // WRONG false | 'truthy'!
我认为您别无选择,只能在实现接口时重复类中的重载(就像您对Exp
所做的那样(;这是一个经过修改的Exp2
,它既实现了接口,又列出了重载:
class Exp2 implements common2 {
test(flag: true): string;
test(flag: false): boolean;
test(flag: boolean): string | boolean {
if (flag) {
return 'truthy'
} else {
return false;
}
}
}
游乐场示例
如果不匹配,则类方法与接口定义不匹配。接口是类必须匹配的约定,而不是影响类声明解释方式的蓝图。
我实际上找到了我想要的关于如何在带有接口的类方法上使用条件类型的答案。
似乎您可以使用带有条件泛型的接口,而不必创建所有可能的重载,只要类型强制转换实现的返回值即可。
所以根据我最初的帖子,这将是:
type ResType<T extends boolean> = T extends true ? string : boolean;
interface common3 {
test<T extends boolean>(flag: T): ResType<T>
}
class Exp3 implements common3 {
test<T extends boolean>(flag: T): ResType<T> {
if (flag) {
return 'truthy' as ResType<T>;
} else {
return false as ResType<T>;
}
}
}
const val3 = new Exp3().test(false); // boolean
const val4 = new Exp3().test(true); // string
打字游戏场