打字稿-通用实现

时间:2018-08-20 05:16:22

标签: typescript

我可以定义一个对象相等的接口,例如:

interface IEquatable<T> {
    readonly equals: (x: T, y: T) => boolean
}

const stringEquatable: IEquatable<string> = {
    equals: (x: string, y: string) => x === y,
}

const numberEquatable: IEquatable<number> = {
    equals: (x: number, y: number) => x === y,
}

stringEquatable.equals("hello", "world") // false
stringEquatable.equals("hello", "hello") // true

numberEquatable.equals(1, 2) // false
numberEquatable.equals(1, 1) // true

但是我也可以像这样简化stringEquatablenumberEquatable的实现:

interface IEquatable<T> {
    readonly equals: (x: T, y: T) => boolean
}

const strictEquatable = {
    equals: <T>(x: T, y: T) => x === y,
}

const stringEquatable: IEquatable<string> = strictEquatable
const numberEquatable: IEquatable<number> = strictEquatable

stringEquatable.equals("hello", "world") // false
stringEquatable.equals("hello", "hello") // true

numberEquatable.equals(1, 2) // false
numberEquatable.equals(1, 1) // true

来自csharp的背景,我对以下行的内容感到困惑

const stringEquatable: IEquatable<string> = strictEquatable

我希望实现IEquatable<string>时需要一种equals类型的实现,而该实现会封闭string类型,但是strictEquatable具有通用实现。

什么打字稿功能使之成为可能?

1 个答案:

答案 0 :(得分:0)

const stringEquatable: IEquatable<string> = strictEquatable起作用的问题的答案什么都没有,或者至少没有什么特别的。这只是一个简单的任务,更插入的问题是为什么strictEquatable的类型与stringEquatable

兼容

与C#不同,Typescript具有结构类型系统。这意味着编译器将根据类型的结构确定类型的兼容性。对于通用函数,这意味着equals的通用版本与将T设置为特定类型的函数签名兼容。让我们考虑一下代码的简化版本:

const genericFn = <T>(x: T, y: T) => x === y;
const stringFn: (x: string, y: string) => boolean = genericFn; // valid for T = string
const wrongReturnTypeFn: (x: string, y: string) => number = genericFn; // error

类型系统以这种方式工作的原因是,类型在编译时被删除,而我们剩下的是普通的旧JavaScript,它不关心函数的参数是什么类型,或者函数在打字稿中具有什么通用参数。