Typescript class 方法 return 基于参数的类型
Typescript class method return type based on parameter
我正在尝试创建一个 class 方法,其 return 类型将取决于 标志参数 [=32= 的 boolean
值]
我在
时成功地做到了这一点
- 使用实现接口的普通函数表达式,
- 或在 class 中直接在 class 主体中声明方法重载时
但是,当我尝试使用由 class.
实现的接口时,我无法执行此操作
我想使用 class 方法的接口实现来实现动态 return 类型。
谢谢!
这里是示例代码,也可以在 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'!
我认为您别无选择,只能在实现接口时在 class 中重复重载(就像您在 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;
}
}
}
如果不这样做,则 class 方法与接口定义不匹配。该接口是您的 class 必须匹配的合同,而不是影响 class 声明的解释方式的蓝图。
我实际上找到了我一直在寻找的关于如何在带有接口的 class 方法上使用条件类型的答案。
您似乎可以使用具有条件泛型的接口,无需创建所有可能的重载,只要您键入实施.
所以根据我原来的 post,这将是:
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
我正在尝试创建一个 class 方法,其 return 类型将取决于 标志参数 [=32= 的 boolean
值]
我在
时成功地做到了这一点- 使用实现接口的普通函数表达式,
- 或在 class 中直接在 class 主体中声明方法重载时
但是,当我尝试使用由 class.
实现的接口时,我无法执行此操作我想使用 class 方法的接口实现来实现动态 return 类型。
谢谢!
这里是示例代码,也可以在 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'!
我认为您别无选择,只能在实现接口时在 class 中重复重载(就像您在 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;
}
}
}
如果不这样做,则 class 方法与接口定义不匹配。该接口是您的 class 必须匹配的合同,而不是影响 class 声明的解释方式的蓝图。
我实际上找到了我一直在寻找的关于如何在带有接口的 class 方法上使用条件类型的答案。
您似乎可以使用具有条件泛型的接口,无需创建所有可能的重载,只要您键入实施.
所以根据我原来的 post,这将是:
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