按会员类型排除类型

时间:2018-09-24 08:54:41

标签: typescript typescript2.8

我有一个函数来处理没有数据到达的情况,否则它将调用回调来处理实际数据。

我使用Typescript 2.8.3。

我已经尝试过这种方法,但是它不起作用:

interface Result { data: string | null; }

function doStuff(
    input: Result,
    cb: (str: Exclude<Result, {data: null}>) => void
): void {
    if (input.data) {
        cb({data: input.data});
    }
}

doStuff({data: "x"}, (result) => {
    alert(result.data.length); // TS2532: Object is possibly 'null'
});

我必须保留Result接口,因为它是某些GQL库生成的代码。此解决方案有效,但对我而言是不可能的:

interface VoidResult { data: null; }
interface NonVoidResult { data: string; }
type Result = VoidResult | NonVoidResult;
function doStuff(
    data: Result,
    cb: (str: NonVoidResult) => void
): void { ... }

实际结果对象不是字符串,而是一个复杂的对象类型,将来可能会有所不同。因此,像cb: (str: string) => void这样写回调也没有用。

是否有一种方法可以从对象成员为null的类型中删除?

1 个答案:

答案 0 :(得分:1)

Result的类型不是联合,它的类型是ht,其成员是联合。您需要从null属性中排除data

interface Result { data: string | null; }

function doStuff(
    input: Result,
    cb: (str: { data: Exclude<Result['data'], null> }) => void
): void {
    if (input.data) {
        cb({data: input.data});
    }
}

doStuff({data: "x"}, (result) => {
    alert(result.data.length); // ok
});

您甚至可以创建从特定类型成员中排除null的类型。如果您的界面上有更多成员,这将很有用:

interface Result { data: string | null; }
type RemoveNullFrom<T, TKey extends keyof T> = Pick<T, Exclude<keyof T, TKey>> & {
    [P in TKey] : Exclude<T[P], null>    
}
function doStuff(
    input: Result,
    cb: (str: RemoveNullFrom<Result, 'data'>) => void
): void {
    if (input.data) {
        cb({data: input.data});
    }
}

doStuff({data: "x"}, (result) => {
    alert(result.data.length); // ok
});