2

这不会编译(游乐场):

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

function myFunctionInternal(params: {
    a: Date,
    b: Date
}) {}

有比 更优雅的解决方法params as any吗?

4

2 回答 2

4

问题是类型保护只影响字段的类型(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);
    }
}
于 2018-07-25T14:43:26.433 回答
2

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

可以这样解决

myFunctionInternal(params as {a,b}); 

或者

myFunctionInternal({a:params.a ,b:params.b});
于 2018-07-25T14:41:43.837 回答