我正在尝试找到一种从功能过载中获得严格的参数歧视的方法。显然,我对此实施的问题是,我的通用类型 t
可以扩展到继承的任何 aorb
props props,因此我在这里获得的错误是完全期望的('{type :“ a”:任何;
我正在寻找的是一种使某种< t实现aorb>
的方法>, customProps
参数被区分为 a
props。
我还试图避免在函数实现参数中使用在返回中的
中使用。
type A = {
a: string
type: 'A'
}
type B = {
b: string
type: 'B'
}
type AorB = A | B
function createAorB(type: A['type'], customProps?: Partial<Omit<A, 'type'>>): A
function createAorB(type: B['type'], customProps?: Partial<Omit<B, 'type'>>): B
function createAorB<T extends AorB>(type: T['type'], customProps: Partial<Omit<T, 'type'>> = {}): T {
if (type === 'A') {
return {
type,
a: customProps.a || '',
}
}
return {
type,
b: customProps.b || '',
}
}
const newA = createAorB('A')
const newB = createAorB('B')
update
如果我执行 aorb
作为返回值:
function createAorB<T extends AorB>(type: T['type'], customProps: Partial<Omit<T, 'type'>> = {}): AorB
我得到两个错误 propert'a''''''''''partial&lt; omit&lt; t; &gt;&gt;'。
和属性'b'在类型'partial&lt; omit&lt; t上,“ type”&gt;&gt;'。 .a
和 customProps.b
行。
I'm trying to find a way to get a strict parameters discrimination from a function overload. Obviously my issue with this implementation is that my generic type T
can be extended to anything inheriting AorB
props so the error I get here is perfectly expected ('{ type: "A"; a: any; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'AorB'.
).
What I'm looking for is a way to have a sort of <T implements AorB>
so that when the parameter type
equals "A"
, the customProps
parameter is discriminated as A
props.
I'm also trying to avoid resorting to use any
within the function implementation parameters or as
within the returns.
type A = {
a: string
type: 'A'
}
type B = {
b: string
type: 'B'
}
type AorB = A | B
function createAorB(type: A['type'], customProps?: Partial<Omit<A, 'type'>>): A
function createAorB(type: B['type'], customProps?: Partial<Omit<B, 'type'>>): B
function createAorB<T extends AorB>(type: T['type'], customProps: Partial<Omit<T, 'type'>> = {}): T {
if (type === 'A') {
return {
type,
a: customProps.a || '',
}
}
return {
type,
b: customProps.b || '',
}
}
const newA = createAorB('A')
const newB = createAorB('B')
UPDATE
If I enforce AorB
as the return value:
function createAorB<T extends AorB>(type: T['type'], customProps: Partial<Omit<T, 'type'>> = {}): AorB
I get both errors Property 'a' does not exist on type 'Partial<Omit<T, "type">>'.
and Property 'b' does not exist on type 'Partial<Omit<T, "type">>'.
on the respective customProps.a
and customProps.b
lines.
发布评论
评论(1)
参数列表 ()表格a ,其中第一个元组元素是判别。看起来像这样:
如果您使用 and 名为
type
和customprops
的变量的元素,您可以 norotateargs args
,然后编译器将使用控制流程分析来缩小ustomprops
检查类型
:如果您碰巧在
aorb
中有很多类型,而不仅仅是a | b
,扩展args
定义可能很乏味。在这种情况下,您可以让编译器为您计算为aorb
的函数,如以下:这使用条件类型推进将复制
aorb
aorb /www.typescriptlang.org/docs/handbook/2/generics.html“ rel =” nofollow noreferrer“> generic type parametert
t ,然后用于使A 联合类型如果t
是联合类型t
中的工会的操作)。您可以验证它的评估与上面的手动定义版本相同。
Playground link to code
The argument list tuple type of
createAOrB()
forms a discriminated union, where the first tuple element is the discriminant. It looks like this:If you use a rest parameter and destructuring assignment to assign the elements to variables named
type
andcustomProps
, you can annotate the rest parameter asArgs
, and then the compiler will use control flow analysis to narrowcustomProps
when you checktype
:If you happen to have lots of types in
AorB
and not justA | B
, it might be tedious to extend theArgs
definition. In this case you can have the compiler compute it for you as a function ofAorB
, like this:This uses conditional type inference to copy
AorB
into a new generic type parameterT
, which is then used to make a distributive conditional type so that[type: T['type'], customProps?: Partial<Omit<T, 'type'>>]
automatically becomes a union type ifT
is a union type (it distributes the operation over unions inT
).You can verify that it evaluates to the same as the manually defined version above.
Playground link to code