typescript - 添加泛型方法会引发类型错误:对象字面量只能指定已知属性,而 __ 类型中不存在 __
问题描述
我的目标是 foo 接受任何扩展Obs<T>
. 但是我收到以下错误。
Argument of type '{ reset: () => number; x: number; set: (x: number) => number; }' is not assignable to parameter of type 'Obs<unknown>'.
Object literal may only specify known properties, and 'reset' does not exist in type 'Obs<unknown>'
片段 A
{
// add a generic method
type Obs<T> = { x: T; set: (x: T) => T }
function createObs<T>(x: T): Obs<T> {
return { x, set: (val: T) => val }
}
function foo<O extends Obs<T>, T>(a: O) {}
const a = createObs(1)
foo({ ...a, reset: () => 1 }) // ❌ now throws the error
}
有趣的是,如果我删除该set
方法,则类型会按预期工作。
片段 B
{
type Obs<T> = { x: T }
function createObs<T>(x: T): Obs<T> {
return { x }
}
function foo<O extends Obs<T>, T>(a: O) {}
const a = createObs(1)
foo({ ...a, reset: () => 1 }) // ✅
}
如何使 Snippet A 与泛型set
方法一起使用?
解决方案
您需要添加额外的通用参数:
// U is extra generic parameter
type Obs<T> = { x: T; set: <U extends T>(x: U) => T }
function createObs<T>(x: T): Obs<T> {
return { x, set: (val: T) => val }
}
function foo<O extends Obs<T>, T>(a: O) { }
const a = createObs(1)
a.set(2) // ok
foo({ ...a, reset: () => 1 })
T
在 中是协变的type Obs<T> = { x: T }
。考虑这个例子:
type Obs<T> = { x: T }
let foo: Obs<number> = { x: 0 }
let bar: Obs<42> = { x: 42 }
foo = bar
bat
可分配给foo
。
但是如果你添加一个set
方法,就像这里:
type Obs<T> = { x: T, set: (x: T) => T }
T
变得不变。
type Obs<T> = { x: T, set: (x: T) => T }
let foo: Obs<number> = { x: 0, set: (val) => val }
let bar: Obs<42> = { x: 42, set: (val) => val }
foo = bar // error
bar = foo // error
bar
不再可分配给foo
。
因此,如果你想让它工作,你需要做set
一个子类型的参数T
。
老实说,我不确定T becomes invariant
。所以,如果你对此有任何争论,我愿意接受批评。
PS 更多关于 *-variance 你会发现here
推荐阅读
- python - 无法使用 Homebrew 在 macOS 中降级 python 版本
- regex - 我如何正则表达式匹配这 3 个场景?
- java - How to add HTTP Response Header by a value of Response Payload in Spring Boot
- jenkins - 从 Jenkins 声明性管道运行 curl 命令
- winapi - Windows如何实现剪贴板格式转换?
- python - 有没有办法只索引 Python 中字符串中项目的一部分?
- scala - 如何根据自定义逻辑在 spark 数据框中删除重复行?
- java - 使用 BufferedWriter 将 arrayList<model class> 写入 txt 文件
- sql-server - 每 24 小时更新一次列
- php - 排序在分页PHP BS-4的下一页上不起作用