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

按成员类型排除类型

  •  1
  • amik  · 技术社区  · 6 年前

    我使用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 回复  |  直到 6 年前
        1
  •  1
  •   Titian Cernicova-Dragomir    6 年前

    类型 Result 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
    });
    

    您甚至可以创建一个排除 从特定类型成员。如果您的接口有更多的成员,这将非常有用:

    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
    });
    
    推荐文章