代码之家  ›  专栏  ›  技术社区  ›  thorn0

TypeScript:在将参数传递给函数调用之前,请检查是否定义了参数的必需属性

  •  2
  • thorn0  · 技术社区  · 6 年前

    这不会编译( playground ):

    function myFunction(params: {
        a: Date,
        b?: Date
    }) {
        if (params.b) {
            myFunctionInternal(params); // ERROR!
        }
    }
    
    function myFunctionInternal(params: {
        a: Date,
        b: Date
    }) {}
    

    有没有比 params as any ?

    2 回复  |  直到 6 年前
        1
  •  4
  •   Titian Cernicova-Dragomir    6 年前

    问题是类型保护只影响字段的类型( params.b 将拥有 undefined 移除)不是整个对象的类型( param 将继续使用类型 { a: Date, b?: Date } )

    我不确定是否可以称之为更优雅,但我们可以创建一个类型保护器,从类型字段中删除未定义的:

    type RemoveOptionalFromField<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>> & { [P in K]-?: T[P] }
    
    function notNull<T, K extends keyof T>(o: T | RemoveOptionalFromField<T, K>, key: K) : o is RemoveOptionalFromField<T, K> {
        return !!o[key];
    }
    
    function myFunction(params: {
        a: Date,
        b?: Date
    }) {
        if (notNull(params, 'b')) {
            params.b.getDate()
            myFunctionInternal(params);
        }
    }
    

    我们甚至可以创建一个包含任意数量键的版本:

    function allNotNull<T, K extends keyof T>(o: T | RemoveOptionalFromField<T, K>, ...keys: K[]) : o is RemoveOptionalFromField<T, K> {
        return keys.every(k => !!o[k]);
    }
    function myFunction(params: {
        a?: Date,
        b?: Date
    }) {
        if (allNotNull(params, 'b', 'a')) {
            params.b.getDate()
            myFunctionInternal(params);
        }
    }
    
        2
  •  2
  •   Muhammed Albarmavi    6 年前

    错误消息说属性“b”在类型{a:Date;b中是可选的?:Date;}但在类型{a:Date;b:Date;}中是必需的

    可以这样解决

    myFunctionInternal(params as {a,b}); 
    

    myFunctionInternal({a:params.a ,b:params.b});