在typescript中,可以输入函数来返回特定实例吗?

时间:2018-02-20 07:30:35

标签: typescript

在打字稿中,我希望有一个功能,比如

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

如果a&lt;将返回a或b。 B'/ P>

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<T>(a: T, b: T): a | b

与我们的工作方式类似,

getThreeOrFive (): 3 | 5

似乎this关键字已经在TS中以这种方式工作,因为我可以编写类似的函数,

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

在TS中有没有办法做到这一点?

1 个答案:

答案 0 :(得分:3)

我的理解是你要保证其中一个输入作为输出返回 - 而不仅仅是匹配类型。

我不相信类型系统可以为你做这个,但是一个好的单元测试可以。

我编写的测试没有用于演示目的的框架 - 但你可以看到围绕这个的单元测试会阻止返回一个新实例:

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

这个输出是:

  

getMinA:非原创A