Typescript`可以用constraint` error的不同子类型实例化

Typescript`可以用constraint` error的不同子类型实例化,typescript,generics,Typescript,Generics,当我返回的结果应该符合函数的预期类型时,我不断发现可能会被一个不同的约束子类型实例化错误,我无法理解我做错了什么。这是我的代码,删除了所有不相关的细节: type User = { } interface BasePageProps { user: User } type GetServerSidePropsResult<P> = | { props: P } type PropsWithUser = <TProps extends BasePageProps

当我返回的结果应该符合函数的预期类型时,我不断发现
可能会被一个不同的约束子类型实例化
错误,我无法理解我做错了什么。这是我的代码,删除了所有不相关的细节:

type User = { }

interface BasePageProps {
    user: User
}

type GetServerSidePropsResult<P> =
  | { props: P }

type PropsWithUser = <TProps extends BasePageProps>(
    callback: (user: User) => Promise<Omit<TProps, 'user'>>
) => Promise<GetServerSidePropsResult<TProps>>

export const testFunc: PropsWithUser = async (callback) => {
    const user = {}
    return { props: {
            user,
            ...(await callback(user))
        } }
}
type User={}
接口BasePageProps{
用户:用户
}
键入GetServerSidePropsResult

= |{props:P} 类型PropsWithUser=( 回调:(用户:用户)=>承诺 )=>承诺 export const testFunc:PropsWithUser=async(回调)=>{ const user={} 返回{props:{ 用户, …(等待回调(用户)) } } }

下面是我得到的错误:

“{user:{};}&Omit”可分配给类型为“TProps”的约束,但“TProps”可以用约束“BasePageProps”的不同子类型实例化

为什么用不同的子类型实例化的潜在
TProps
是一个问题?我怎样才能修好它


注意:您可能会注意到这些类型取自Next.js。但是,此问题与Next.js本身无关,因此请不要将其附加到此问题。

您的函数的有效签名为:

type-PropsWithUser=(
回调:(用户:用户)=>承诺
)=>承诺
或者,您可以删除一些重复:

type-PropsWithUser=Promise
)=>承诺
一个反例证明编译器正确地提出了关于代码的错误。让我们定义一个扩展
BasePageProps
但不通过函数结果类型检查的
TProps
类型的具体示例:

type User={}
键入另一个用户={a:string}
接口TProps{
用户:另一个用户
}
接口BasePageProps{
用户:用户
}
类型Eq=TProps扩展BasePageProps?true:false//type Eq=true
类型PropsWithUser=(
回调:(用户:用户)=>承诺
)=>承诺

因此,函数应该返回类型为
Promise
的结果。这显然不是

正如错误所说:
“{user:{};}&Omit”可分配给类型为“TProps”的约束,但是“TProps”可以用约束“BasePageProps”的不同子类型实例化。

type User={}
接口BasePageProps{
用户:用户
}
键入另一个用户={a:string}
接口具体程序{
用户:另一个用户
}
//{user:{};}&Omit是可分配的
//到TProps类型的约束(即BasePageProps)
常量a:BasePageProps={user:{}
//但是“TProps”可以用不同的
//约束“BasePageProps”的子类型(即ConcreteTProps)
//不能使用BasePageProps的子类型
//分配给{user:user}
常量b:ConcreteTProps={user:{}}//错误

我没有意识到字段类型也可以在扩展接口上扩展,谢谢!