Typescript泛型函数重载与rest类型

时间:2018-02-13 15:01:34

标签: typescript generics

是否有任何方法(特殊语法)将类似rest参数的内容应用于TypeScript中的模板?

如果问题不清楚,请查看以下示例和评论。

问题是 - 我可以在这里申请休息...Types

function mixIt<A, B>   (a: A, b: B): A & B;
function mixIt<A, B, C>(a: A, b: B, c: C): A & B & C;

/* 
 * ??
 * If I would like to add D, E, F, etc, do I have to overwrite it like above?
 */

function mixIt<A, B, C>(...args: any[]): any{
    let mixin = <A & B & C> {};

    args.forEach( obj => {
        for(let key in obj) {
            if( ! mixin.hasOwnProperty(key) ) {
                (<any>mixin)[key] = obj[key];
            }
        }
    });

    return mixin;
}

FYI - 错误检测符合预期:

class X {x: number = 7;}
class Y {y: string = 'ok';}
class Z {z: boolean = false;}

let x = new X;
let y = new Y;
let z = new Z;

let xy = mixIt(x, y);
let xyz = mixIt(x, y, z);

xyz.z; // Ok;
xy.z; // Error - as expected. VS Code editor also highlights it

1 个答案:

答案 0 :(得分:4)

修改 由于原始答案打字稿在3.0中的rest参数中添加了对元组的支持。有了这个,我们可以在没有所有重载的情况下实现所需的结果:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <script type="text/javascript">
    $(function () {
        $("#ddlPassport").change(function () {
            // Airtel
            if ($(this).val() == "airtel") {
                $("#airtel").show();
            } else {
                $("#airtel").hide();
            }
            
            //DishTV
            if ($(this).val() == "dishtv") {
                $("#dishtv").show();
            } else {
                $("#dishtv").hide();
            } 
        });
    });

</script>
<select id="ddlPassport">
    <option title="Airtel DTH" value="airtel" id="">Airtel DTH</option>
    <option title="Reliance" value="reliance" id="">Big TV/Reliance Digital TV</option>
    <option title="SUNTV" value="suntv">SUN TV</option>
    <option title="Videocon" value="videocon">Videocon D2H</option>
    <option title="DISHTV" value="dishtv">DISH TV</option>
    <option title="Tata Sky" value="tatasky">TATA SKY</option>

</select>         
<div class="form-group form-group-icon-left" id="airtel" style="display:none;">
         <i class="fa fa-pencil input-icon input-icon-highlight"></i>
             <label for="txtMobileNo"><span id="">Customer ID :</span></label>
                <input type="text" class="form-control" name="txtMobileNo" id="" placeholder="Customer ID">
     </div>
     <div class="form-group form-group-icon-left" id="dishtv" style="display:none;">
         <i class="fa fa-pencil input-icon input-icon-highlight"></i>
             <label for="txtMobileNo"><span id="">Mobile No. or Card No. :</span></label>
                <input type="text" class="form-control" name="txtMobileNo" id="" placeholder="Mobile No. or Card No.">
     </div>
     <div class="form-group form-group-icon-left" id="reliance-sun" style="display:none;">
         <i class="fa fa-pencil input-icon input-icon-highlight"></i>
              <label for="txtMobileNo"><span id="">Smart Card No :</span></label>
                <input type="text" class="form-control" name="txtMobileNo" id="" placeholder="Smart Card No.">
     </div>

原始回答

目前无法使用可变数量的类型参数,只有proposal on this

目前执行此操作的唯一方法是根据需要为函数添加任意数量的签名,因此在您的情况下,这将是:

type UnionToIntersection<U> = 
    (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

function mixIt<T extends any[]>(...args: T): UnionToIntersection<T[number]>{ 
    let mixin: any =  {};

    args.forEach( obj => {
        for(let key in obj) {
            if( ! mixin.hasOwnProperty(key) ) {
                mixin[key] = obj[key];
            }
        }
    });

    return mixin;
}