简体   繁体   English

在打字稿中,是否可以键入函数以返回特定实例?

[英]In typescript, can a function be typed to return a particular instance?

In typescript I would like to have a function, like 在打字稿中我想有一个功能,像

getMin<T>(a: T, b: T): T

Which will return either a, or b such that, if a < b 如果a <b,它将返回a或b

getMin(a, b) === a

Is always true. 永远是真的。 For example, the following function would not qualify: 例如,下面的函数将没有资格:

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);
  }
}

Because getMin(a, b) === a will return false since a is not referentially equal to the return value of getMin . 因为getMin(a, b) === a将返回false因为a不参考等于getMin的返回值。 This is because getMin returns a copy of a , not the a that was passed into the function. 这是因为getMin返回副本a ,而不是a已传递到函数。 What I want is a function that returns either of its inputs, something like, 我想要的是一个返回其输入之一的函数,例如,

const getMin = (a: IUser, b: IUser) => {
  if (min(a.userId, b.userId) === a) {
    return a; // reference
  } else {
    return b;
  }
}

That way, if I wrote a function that was accidentally creating a copy when I wanted it to return one of the given references, it would be a compile time error. 这样,如果我编写了一个函数,当我希望它返回给定的引用之一时意外创建了一个副本,那将是编译时错误。 I'm imagining a type signature like, 我在想像这样的类型签名,

getMin<T>(a: T, b: T): a | b

Similar to how we can do, 与我们的做法类似,

getThreeOrFive (): 3 | 5

It seems like the this keyword already works this way in TS, since I can write a function like, 看来this关键字已经在TS中以这种方式工作了,因为我可以编写如下函数:

this.doSomething = (): this => { /* does something */ return this }

Is there some way to do this in TS? 在TS中有什么方法可以做到这一点吗?

My understanding is that you want to guarantee that one of the inputs is returned as the output - not just a matching type. 我的理解是,您想保证输入之一作为输出返回,而不仅仅是匹配类型。

I don't believe a type system can do this for you, but a good unit test can. 我不相信类型系统可以为您做到这一点,但是良好的单元测试可以。

I have written the test without a framework for demonstration purposes - but you can see that a unit test around this would prevent a new instance from being returned: 我出于演示目的编写了没有框架的测试-但您可以看到围绕此进行的单元测试将阻止返回新实例:

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');
}

The output from this is: 输出是:

getMinA: Not original A getMinA:不是原始A

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM