"Object is possibly undefined" 当那不可能时
"Object is possibly undefined" when that is not possible
我正在定义一个 CDK 构造,它接收 props
对象并将其传递给 PythonFunction
的环境。由于环境参数需要非空字符串值(并且一些道具可以为空或非字符串类型),我有以下内容:
export interface MyConstructProps {
key1: string,
key2: string,
key3?: string
key4?: SomeOtherType
[key: string]: string | SomeOtherType | undefined
}
export class MyConstruct extends cdk.Construct {
constructor(scope: Construct, id: string, props: MyConstructProps) {
...
// within PythonFunction definition
environment: Object.fromEntries(
Object.entries(props)
.filter(([k, v]) => v !== undefined)
.map(([k, v]) => [k, v.toString()])
),
...
}
但是,这会产生错误 - v.toString()
中的 v
带有红色下划线,并带有消息 TS2532: Object is possibly 'undefined'.
.
我发现颠倒 map
和 filter
的顺序可以编译并按预期工作:
Object.entries(props)
.map(([k, v]) => {
if (v === undefined) {
return [k, v]
} else {
return [k, v.toString()]
}
})
.filter(([k, v]) => v !== undefined)
如何以 TypeScript 识别类型限制的方式过滤掉数组中的值?
这与顺序关系不大,而与您使用的 narrowing if 语句允许 TS 正确推断这一事实有关。 IE,它也将按此顺序工作。
Object.entries(props)
.filter(([k, v]) => v !== undefined)
.map(([k, v]) => {
if (v === undefined) {
return [k, v]
} else {
return [k, v.toString()]
}
})
Filter 假定其 return 值始终与其谓词匹配相同的形状,这只是对其类型的简单限制。 TS 无法很好地评估 scope-boundaries 中的 compile-code。由于各种原因,IIRC 也没有尝试这样做,在许多情况下,模块可能会被扩充(从而改变实现),或者如果您愿意,您可以自己扩充(and/or 重载)声明。 https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation, OR to declare a different type only syntax here,即。 declare global {...}
,使用您自己的类型泛型来描述 return 值。
但没有太多意义,因为它与下面的答案一样冗长
你可以使用 as
(Object.entries(props)
.filter(([k, v]) => v !== undefined) as [string, string][])
.map(([k, v]) => [k, v.toString()])
上查看此内容
更简单的方法是使用断言:
Object.entries(props)
.filter(([k, v]) => v !== undefined)
.map(([k, v]) => [k, v!.toString()])
!
用作 non-nullish 断言:
let nullable: string | undefined = "hello world";
nullable!.slice(0, 5); // "hello", no error
我正在定义一个 CDK 构造,它接收 props
对象并将其传递给 PythonFunction
的环境。由于环境参数需要非空字符串值(并且一些道具可以为空或非字符串类型),我有以下内容:
export interface MyConstructProps {
key1: string,
key2: string,
key3?: string
key4?: SomeOtherType
[key: string]: string | SomeOtherType | undefined
}
export class MyConstruct extends cdk.Construct {
constructor(scope: Construct, id: string, props: MyConstructProps) {
...
// within PythonFunction definition
environment: Object.fromEntries(
Object.entries(props)
.filter(([k, v]) => v !== undefined)
.map(([k, v]) => [k, v.toString()])
),
...
}
但是,这会产生错误 - v.toString()
中的 v
带有红色下划线,并带有消息 TS2532: Object is possibly 'undefined'.
.
我发现颠倒 map
和 filter
的顺序可以编译并按预期工作:
Object.entries(props)
.map(([k, v]) => {
if (v === undefined) {
return [k, v]
} else {
return [k, v.toString()]
}
})
.filter(([k, v]) => v !== undefined)
如何以 TypeScript 识别类型限制的方式过滤掉数组中的值?
这与顺序关系不大,而与您使用的 narrowing if 语句允许 TS 正确推断这一事实有关。 IE,它也将按此顺序工作。
Object.entries(props)
.filter(([k, v]) => v !== undefined)
.map(([k, v]) => {
if (v === undefined) {
return [k, v]
} else {
return [k, v.toString()]
}
})
Filter 假定其 return 值始终与其谓词匹配相同的形状,这只是对其类型的简单限制。 TS 无法很好地评估 scope-boundaries 中的 compile-code。由于各种原因,IIRC 也没有尝试这样做,在许多情况下,模块可能会被扩充(从而改变实现),或者如果您愿意,您可以自己扩充(and/or 重载)声明。 https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation, OR to declare a different type only syntax here,即。 declare global {...}
,使用您自己的类型泛型来描述 return 值。
但没有太多意义,因为它与下面的答案一样冗长
你可以使用 as
(Object.entries(props)
.filter(([k, v]) => v !== undefined) as [string, string][])
.map(([k, v]) => [k, v.toString()])
上查看此内容
更简单的方法是使用断言:
Object.entries(props)
.filter(([k, v]) => v !== undefined)
.map(([k, v]) => [k, v!.toString()])
!
用作 non-nullish 断言:
let nullable: string | undefined = "hello world";
nullable!.slice(0, 5); // "hello", no error