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:{}}//错误
我没有意识到字段类型也可以在扩展接口上扩展,谢谢!