当排除扩展接口时,打字稿为什么给出类型“从不”

时间:2019-01-02 16:05:50

标签: typescript

我创建了一个剥离接口对象的函数。但是,Typescript(版本3.2.2)现在应该声明其类型为never,而该类型应该是具有属性child

的类型。
interface Child extends Parent {
    child: string
}

interface Parent {
    parent: string
}

const a: Child = { child: "", parent: "" }

const b = removeParent(a);

function removeParent<T extends Parent>(obj: T) {
    delete obj.parent;
    return obj as Exclude<T, Parent>;
}

// b is now type never...

这确实有效:

function removeParent<T extends Parent>(obj: T) {
    delete obj.parent;
    type Without<T, K> = Pick<T, Exclude<keyof T, K>>;
    return obj as Without<T, "parent">;
}

但是我想要一个通用的解决方案,不需要我写出要排除的类型。

1 个答案:

答案 0 :(得分:4)

我认为您不希望Exclude<T, Parent>

排除实际上是: type Exclude<T, U> = T extends U ? never : T

因此,由于T在您的用法中扩展了never,因此您的返回类型将返回Parent

我认为您真正追求的是: Pick<T, Exclude<keyof T, keyof Parent>>

所以您说的是'选择T在父级中不存在的所有属性'

function removeOneAndTwo<T extends Parent>(obj: T): Pick<T, Exclude<keyof T, keyof Parent>> {
  delete obj.one;
  delete obj.two;
  return obj;
}