如何使类型推断在TypeScript中工作

如何使类型推断在TypeScript中工作,typescript,generics,type-inference,Typescript,Generics,Type Inference,我有几个签名重载的函数 // 1: overwrite function extend<T>(d: T, ...s: Partial<T>[]): T; // 2: shallow copy & overwrite function extend<T>(o: {}, d: T, ...s: Partial<T>[]): T; // 3: overwrite & extend function extend<T, S ext

我有几个签名重载的函数

// 1: overwrite
function extend<T>(d: T, ...s: Partial<T>[]): T;

// 2: shallow copy & overwrite
function extend<T>(o: {}, d: T, ...s: Partial<T>[]): T;

// 3: overwrite & extend
function extend<T, S extends T>(d: T, ...s: Partial<S>[]): Partial<S>;

// 4: shallow copy & overwrite & extend
function extend<T, S extends T>(o: {}, d: T, ...s: Partial<S>[]): Partial<S>;

// implementation
function extend(d: any, ...s: any[]): any {
    for (let src of s) {
        for (let prop in src) {
            if (src.hasOwnProperty(prop)) {
                d[prop] = src[prop];
            }
        }
    }
    return d;
}
//1:覆盖
函数扩展(d:T,…s:Partial[]):T;
//2:浅复制和覆盖
函数扩展(o:{},d:T,…s:Partial[]):T;
//3:覆盖和扩展
函数扩展(d:T,…s:Partial[]):Partial;
//4:浅复制、覆盖和扩展
函数扩展(o:{},d:T,…s:Partial[]):Partial;
//实施
函数扩展(d:any,…s:any[]):any{
对于(让src/s){
用于(让支柱插入src){
如果(src.hasOwnProperty(prop)){
d[prop]=src[prop];
}
}
}
返回d;
}
为了使开发更容易,我希望通过类型推断的方式完成所有代码

1号签名完美无瑕。支持类型推断,当我开始键入
s
对象的属性时,我就可以完成代码

我还了解签名3和签名4的类型推断是不可能的,因为类型
S
不能从任何地方推断出来,特别是因为参数的类型是
部分

但我不确定签名2是否正确。似乎可以根据第二个参数推断
S
的类型,除非我明确提供泛型类型参数,否则情况并非如此

问题:
如何同时完成1和2的类型推断(和代码完成)?或者为什么不可能?我看到的部分问题是,我不知道如何为空对象文本创建类型别名。因为我认为这将是签名2的解决方案。

我看到的问题是重载非常模糊,它们提供的值很少,因为它们很容易从一个到另一个。。我试着看看如何让它们发挥作用,但从我所看到的情况来看,如果第二个过载不令人满意,它只会下降到第三个或第四个过载,因此第二个过载没有什么价值。@TitianCernicova Dragomir有什么建议吗?我对这些签名的意义感到困惑;你能解释他们的意图吗?查看
extend()
的实现,看起来您正在创建。是这样吗?如果是这样,您可能想看看。@jcalz:基本上是的,因为
Object.assign
在我的代码中实际上不可用。但是从调用签名来看,它们是非常基本的,因为它们假设一个对象总是扩展
target
,而不一定覆盖它的属性。这仅仅意味着源对象上没有代码完成,即使大部分时间assign/extend用于覆盖属性或添加一些缺少的属性,但仍保留在
目标的类型定义中。可能有多个功能用于多个目的?我的意思是,如果你不想扩展目标,“扩展”这个名字可能不太好;实现可能也会有所不同,因为您可能应该只枚举目标的属性,而不是源的属性……我看到的问题是重载非常模糊,它们提供的值很少,因为它们很容易从一个到另一个。。我试着看看如何让它们发挥作用,但从我所看到的情况来看,如果第二个过载不令人满意,它只会下降到第三个或第四个过载,因此第二个过载没有什么价值。@TitianCernicova Dragomir有什么建议吗?我对这些签名的意义感到困惑;你能解释他们的意图吗?查看
extend()
的实现,看起来您正在创建。是这样吗?如果是这样,您可能想看看。@jcalz:基本上是的,因为
Object.assign
在我的代码中实际上不可用。但是从调用签名来看,它们是非常基本的,因为它们假设一个对象总是扩展
target
,而不一定覆盖它的属性。这仅仅意味着源对象上没有代码完成,即使大部分时间assign/extend用于覆盖属性或添加一些缺少的属性,但仍保留在
目标的类型定义中。可能有多个功能用于多个目的?我的意思是,如果你不想扩展目标,“扩展”这个名字可能不太好;实现可能也应该不同,因为您应该只枚举目标的属性,而不是源的属性。。。