我对以下几段代码很困惑:
$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
。
我缺少什么,如何使此代码编译?
答案 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
或者没有不必要引入null
和undefined
的版本:
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