在下面的代码中,from
和 to
的类型都是泛型类型 T
,但只需检查 to
is string
并不能让 TypeScript 理解 from
也是 string
。我不想还检查 from
,有什么方法可以通过一次检查来完成此操作吗?
function mergeData<T>(from: T, to: T) : T {
if(typeof to === 'string')
return to + from // Error : Type 'string' is not assignable to type 'T'.
if(Object.prototype.toString.call(to).slice(8, -1) === 'Array')
return to.concat(from) // Property 'concat' does not exist on type 'T'.
// ...
}
我尝试这样做:
interface Parent {
name: string
}
interface ChildNumber extends Parent{
name: string
number: number
}
interface ChildObject extends Parent {
name: string
object: { a: number }
}
function isChildNumber(obj: any) : obj is ChildNumber {
return 'number' in obj
}
function isChildObject(obj: any) : obj is ChildObject {
return 'object' in obj
}
function mergeData<T extends Parent>(from: T, to: T) : T {
if(isChildNumber(from))
return to.number + from.number // Error : Property 'number' does not exist on type 'T'.
if(isChildObject(from))
return to.object.a + from.object.a // Property 'object' does not exist on type 'T'.
}
此代码没有进行任何更改。 ;(
最佳答案
这是对函数签名的完全有效的调用:
mergeData<string | number>('asd', 123)
如果您的函数以这种方式调用,则 typeof to === 'string'
将返回 true
,但 from
会返回类型为number
。
to
和 from
都保证是 T
的子类型,但它们可能是 T
的不同子类型>。这意味着您需要在运行时测试这两个变量才能确定。
关于typescript - 有没有办法在 typescript 中用一种类型检查来检查两种泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68488506/