我可以定义一个对象相等的接口,例如:
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
但是我也可以像这样简化stringEquatable
和numberEquatable
的实现:
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
具有通用实现。
什么打字稿功能使之成为可能?
答案 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,它不关心函数的参数是什么类型,或者函数在打字稿中具有什么通用参数。