在typescript中,可以键入函数以返回特定实例吗?
在typescript中,我想要一个函数,比如在typescript中,可以键入函数以返回特定实例吗?,typescript,Typescript,在typescript中,我想要一个函数,比如 getMin(a:T,b:T):T 它将返回a或b,如果a{/*做某事*/返回this} 在TS中有什么方法可以做到这一点吗?我的理解是,您希望保证其中一个输入作为输出返回,而不仅仅是匹配类型 我不相信类型系统可以为您做到这一点,但是一个好的单元测试可以做到 我编写的测试没有用于演示目的的框架,但您可以看到,围绕此进行的单元测试将阻止返回新实例: interface IUser { userId: number; } class User
getMin(a:T,b:T):T
它将返回a或b,如果a
getMin(a,b)==a
这永远是真的。例如,以下函数将不符合条件:
const getMin = (a: IUser, b: IUser): IUser => {
if (min(a.userId, b.userId) === a) {
return new User(a); // copy constructor
} else {
return new User(b);
}
}
因为getMin(a,b)==a将返回false
,因为a
在引用上不等于getMin
的返回值。这是因为getMin
返回的是a
的副本,而不是传递到函数中的a
。我想要的是一个函数,它返回它的任何一个输入,比如
const getMin = (a: IUser, b: IUser) => {
if (min(a.userId, b.userId) === a) {
return a; // reference
} else {
return b;
}
}
这样,如果我编写了一个函数,当我希望它返回一个给定的引用时,它意外地创建了一个副本,那么这将是一个编译时错误。我在想象一个类型签名,比如
getMin(a:T,b:T):a | b
就像我们能做的一样
getThreeOrFive():3 | 5
似乎在TS中,this
关键字已经以这种方式工作了,因为我可以编写这样的函数
this.doSomething=():this=>{/*做某事*/返回this}
在TS中有什么方法可以做到这一点吗?我的理解是,您希望保证其中一个输入作为输出返回,而不仅仅是匹配类型
我不相信类型系统可以为您做到这一点,但是一个好的单元测试可以做到
我编写的测试没有用于演示目的的框架,但您可以看到,围绕此进行的单元测试将阻止返回新实例:
interface IUser {
userId: number;
}
class User implements IUser {
userId: number;
constructor(u: IUser) {
this.userId = u.userId;
}
}
const getMinA = (a: IUser, b: IUser): IUser => {
if (a.userId < b.userId) {
return new User(a); // copy constructor
} else {
return new User(b);
}
}
const getMinB = (a: IUser, b: IUser): IUser => {
if (a.userId < b.userId) {
return a;
} else {
return b;
}
}
const a = new User({ userId: 1 });
const b = new User({ userId: 2 });
if (getMinA(a, b) === a) {
// Okay
} else {
alert('getMinA: Not original A');
}
if (getMinB(a, b) === a) {
// Okay
} else {
alert('getMinB: Not original A');
}
接口IUser{
userId:number;
}
类用户实现IUser{
userId:number;
构造函数(u:IUser){
this.userId=u.userId;
}
}
常量getMinA=(a:IUser,b:IUser):IUser=>{
if(a.userId{
if(a.userId
此操作的输出为:
盖特米娜:不是原创的
我的理解是,您希望保证其中一个输入作为输出返回,而不仅仅是匹配类型
我不相信类型系统可以为您做到这一点,但是一个好的单元测试可以做到
我编写的测试没有用于演示目的的框架,但您可以看到,围绕此进行的单元测试将阻止返回新实例:
interface IUser {
userId: number;
}
class User implements IUser {
userId: number;
constructor(u: IUser) {
this.userId = u.userId;
}
}
const getMinA = (a: IUser, b: IUser): IUser => {
if (a.userId < b.userId) {
return new User(a); // copy constructor
} else {
return new User(b);
}
}
const getMinB = (a: IUser, b: IUser): IUser => {
if (a.userId < b.userId) {
return a;
} else {
return b;
}
}
const a = new User({ userId: 1 });
const b = new User({ userId: 2 });
if (getMinA(a, b) === a) {
// Okay
} else {
alert('getMinA: Not original A');
}
if (getMinB(a, b) === a) {
// Okay
} else {
alert('getMinB: Not original A');
}
接口IUser{
userId:number;
}
类用户实现IUser{
userId:number;
构造函数(u:IUser){
this.userId=u.userId;
}
}
常量getMinA=(a:IUser,b:IUser):IUser=>{
if(a.userId{
if(a.userId
此操作的输出为:
盖特米娜:不是原创的
那么,您希望函数签名强制执行实现中正在进行的复制吗?不,不,相反!我希望签名强制执行返回值在引用上等于其中一个输入。为了更清楚起见,我编辑了我的问题。因此,您希望函数签名强制执行在实现中进行复制吗?不,不,相反!我希望签名强制执行返回值在引用上等于其中一个输入。为了更清楚,我编辑了我的问题。谢谢你的建议。您确定类型系统不能执行此操作吗?我觉得它可以。。。但是我很想知道为什么你认为一个人不能。@Ziggy不确定“类型系统”,但是typescript类型系统不能处理类型。执行此检查的系统需要分析应用程序,以推断是否会返回相同的引用。在本例中,这可以针对单个方法完成,但是想象一下在编译时尝试跨多个调用跟踪引用。这在理论上是可能的,但会给人留下深刻印象。我会把这样一个系统称为“引用系统”,而不是“类型系统”。如果它有一个类型注释,那么我们就不需要通过程序跟踪引用,因为每个类型良好的函数要么返回该引用,要么不返回该引用。因此,如果f
通过引用返回它的一个参数a
,并且f
调用g
,而该参数不与a
,那么这将是一个编译时错误。不需要下降到g
,因为我们知道g
的返回类型。如果f
调用h
,通过ref返回其参数,那么我们知道h(a)
的返回类型仍然是a
。但是我一般没有问它是否可能:我问它在typescript中是否可能。如果你知道不是,并且你在回答中表达了这一点,我可以接受你的回答。谢谢你的建议。您确定类型系统不能执行此操作吗?我觉得它可以。。。但是我很想知道为什么你认为一个人不能。@Ziggy不确定“类型系统”,但是typescript类型系统不能处理类型。执行此检查的系统需要分析应用程序,以推断是否存在相同的引用