TypeScript:Generic仅使用可选键扩展对象

TypeScript:Generic仅使用可选键扩展对象,typescript,Typescript,我有一个重载函数 export function someFunc<P extends undefined>(): () => string export function someFunc<P extends object>(): (params: P) => string export function someFunc<P extends object | undefined>() { // ...implementation }

我有一个重载函数

export function someFunc<P extends undefined>(): () => string

export function someFunc<P extends object>(): (params: P) => string

export function someFunc<P extends object | undefined>() {
    // ...implementation
}
过载看起来像这样:

export function someFunc<P extends NoOptionalKeys>(): (params?: P) => string
function someFunc<P extends object | undefined>(): (...params:
    P extends undefined ? [] :
    Partial<P> extends P ? [P?] :
    [P]
) => string;
function someFunc() {
    return null!
}
导出函数someFunc():(参数?:P)=>字符串

嗯,我不知道我是否见过以这种方式使用重载;我假设您希望调用方手动指定
P
generic,然后让编译器从中选择调用签名,因为调用签名都是零参数,没有任何东西可以自动推断
P
。所以我假设你在寻找这样的东西:

const fUndef = someFunc<undefined>();
// () => string
const fSomeReq = someFunc<{ a: string, b?: string }>();
// (params: {a: string, b?: string}) => string;
const fNoReq = someFunc<{ a?: string, b?: string }>();
// (params?: {a?: string, b?: string}) => string;
我把这当作第二个过载;它需要位于常规
对象
重载之前,以便具有更高的优先级。如果您选中此代码,则上面的
fUndef
fSomeReq
fNoReq
将按您期望的方式键入


另一种可能的方法是只给出一个调用签名,并使用条件类型来计算函数输出类型。大概是这样的:

export function someFunc<P extends NoOptionalKeys>(): (params?: P) => string
function someFunc<P extends object | undefined>(): (...params:
    P extends undefined ? [] :
    Partial<P> extends P ? [P?] :
    [P]
) => string;
function someFunc() {
    return null!
}
这可能更明显地与您的过载有关。任何一种方法都应该有效


好吧,希望这会有帮助;祝你好运


嗯,我不知道我是否见过以这种方式使用重载;我假设您希望调用方手动指定
P
generic,然后让编译器从中选择调用签名,因为调用签名都是零参数,没有任何东西可以自动推断
P
。所以我假设你在寻找这样的东西:

const fUndef = someFunc<undefined>();
// () => string
const fSomeReq = someFunc<{ a: string, b?: string }>();
// (params: {a: string, b?: string}) => string;
const fNoReq = someFunc<{ a?: string, b?: string }>();
// (params?: {a?: string, b?: string}) => string;
我把这当作第二个过载;它需要位于常规
对象
重载之前,以便具有更高的优先级。如果您选中此代码,则上面的
fUndef
fSomeReq
fNoReq
将按您期望的方式键入


另一种可能的方法是只给出一个调用签名,并使用条件类型来计算函数输出类型。大概是这样的:

export function someFunc<P extends NoOptionalKeys>(): (params?: P) => string
function someFunc<P extends object | undefined>(): (...params:
    P extends undefined ? [] :
    Partial<P> extends P ? [P?] :
    [P]
) => string;
function someFunc() {
    return null!
}
这可能更明显地与您的过载有关。任何一种方法都应该有效


好吧,希望这会有帮助;祝你好运


谢谢您的精彩回答!多亏了你,我才明白我所做的一切毫无意义。最后我用
P扩展部分

extends P?对象:永远不要

谢谢你的精彩回答!多亏了你,我才明白我所做的一切毫无意义。最后我用
P扩展部分

extends P?对象:从不