为什么可选对象成员的类型为“从不”?

时间:2019-05-09 12:15:11

标签: typescript typescript-generics

我对以下几段代码很困惑:

$fooBar->removeFooCollection(
     $fooBar->getFooCollection()
);
$entityManager->persist($fooBar);
$entityManager->flush();

在这里,interface Test { one?: number, two?: { n: number } } const test: Test = { one: 1, two: { n: 2 } } function prop<O, K extends keyof O>(obj: O, key: K): O[K] { return obj[key] } let x = prop(test, 'one') // Compiles ok, x is number | undefined let y = prop(test.two, 'n') // Argument of type '"n"' is not assignable to parameter of type 'never'. 键入为x,这是预期的。但是number | undefined被键入为y。这是为什么?我希望改为never

我缺少什么,如何使此代码编译?

1 个答案:

答案 0 :(得分:0)

失败的原因是在strictNullChecks下,可选字段被键入为OriginalType | undefined。只能访问联合的普通成员,并且由于undefined没有成员,因此会导致never

如果您将obj输入为obj: O | undefined | null,则会从null中取出O

function prop<O, K extends keyof O>(obj: O | undefined | null, key: K): O[K] | undefined | null {
    return obj && obj[key]
}

let x = prop(test, 'one')   // number | null | undefined
let y = prop(test.two, 'n') // number | null | undefined

或者没有不必要引入nullundefined的版本:

interface Test {
    one?: number,
    two?: {
        n: number
    }
    req: {
        n: number
    }
}

const test: Test = {
    one: 1,
    two: { n: 2 },
    req: { n: 2 }
}

function prop<O, K extends keyof Exclude<O, undefined | null>>(obj: O, key: K): Extract<O, undefined | null> | Exclude<O, undefined | null>[K]
function prop<K extends PropertyKey, V>(obj: Record<K, undefined | null | V>, key: K): V | undefined | null {
    return obj && obj[key]
}

let x = prop(test, 'one')   // number | undefined
let y = prop(test.two, 'n') // number | undefined
let z = prop(test.req, 'n') // number