我想创建一个“区分联合类型”,不需要传递区分值。
这是我当前的代码:
interface Single<T> {
multiple?: false // this is optional, because it should be the default
value: T
onValueChange: (value: T) => void
}
interface Multi<T> {
multiple: true
value: T[]
onValueChange: (value: T[]) => void
}
type Union<T> = Single<T> | Multi<T>
为了进行测试,我使用了这个
function typeIt<T>(data: Union<T>): Union<T> {
return data;
}
const a = typeIt({ // should be Single<string>
value: "foo",
onValueChange: (value) => undefined // why value is of type any?
})
const b = typeIt({ // should be Single<string>
multiple: false,
value: "foo",
onValueChange: (value) => undefined
})
const c = typeIt({ // should be Multi<string>
multiple: true,
value: ["foo"],
onValueChange: (value) => undefined
})
但是我收到很多错误和警告...:
在const a
的{{1}}中,参数onValueChange
的类型为value
。明确设置any
时(例如在multiple: false
中),它会正确推断为const b
。
string
根本不起作用。我收到此错误:“类型'string'无法分配给类型'string []'” 。
您知道如何解决此问题吗?
我已使用此代码创建了TypeScript Playground
答案 0 :(得分:2)
我认为编译器无法轻易推断出回调中value
参数的类型,因为在检查回调时仍无法确定对象文字的类型。
如果工会成员很多,那么一个可以按预期工作的解决方案是使用多个重载:
export interface Single<T> {
multiple?: false // this is optional, because it should be the default
value: T
onValueChange: (value: T) => void
}
interface Multi<T> {
multiple: true
value: T[]
onValueChange: (value: T[]) => void
}
type Union<T> = Single<T> | Multi<T>
function typeIt<T>(data: Single<T>): Single<T>
function typeIt<T>(data: Multi<T>): Multi<T>
function typeIt<T>(data: Union<T>): Union<T> {
return data;
}
const a = typeIt({ // is Single<string>
value: "foo",
onValueChange: (value) => undefined // value is typed as expected
})
const b = typeIt({ // is Single<string>
multiple: false,
value: "foo",
onValueChange: (value) => undefined
})
const c = typeIt({ // is be Multi<string>
multiple: true,
value: ["foo"],
onValueChange: (value) => undefined
})