属性 在联合类型上不存在
Property does not exist on type union
我已经通过 Whosebug 问题进行了搜索,但在我的案例中没有找到所需的答案。
我有
interface FruitBox {
name: string
desc: {
'orange': number;
'banana': number;
}
}
interface IceBox {
name: string
}
interface Vegabox {
name: string
desc: {
'tomato': number;
'potato': number;
}
}
type UnionBox = FruitBox | Vegabox | IceBox;
我正在尝试实现什么
type Ship = Record<string, (description: UnionBox['desc'] | UnionBox['name']) => void>;
我正在尝试将 description
属性 分配给 UnionBox['desc']
类型,如果 desc
参数不存在,则将其分配给 UnionBox['name']
收到下一个错误:
Property 'desc' does not exist on type 'UnionBox'
很高兴得到任何帮助或提示
ps。我知道一定有一些奇怪的算法,只是不确定以哪种方式查看
您示例中的 UnionBox
可以是以下类型之一 - FruitBox
、Vegabox
或 IceBox
。 IceBox
是让 Typescript 不开心的地方——它不包含 属性 desc
。想象一下,有一个 IceBox
类型的对象,然后将它传递给一个函数,该函数将 UnionBox
作为参数,然后使用 属性 desc
- 它会访问一个非现有一个。
I'm trying to assign a description property to a type of UnionBox['desc'] and if desc parameter doesn't exist, then assign it to the UnionBox['name']
我不确定您希望它如何工作,因为在您的示例中描述只是简单地输入为字符串或字符串 - |运算符将简单地创建一个联合。但我想你可以简单地接受 unionBox: UnionBox
作为参数,并在其中添加一个逻辑,如果 desc
不存在,则 unionBox.desc ?? unionBox.name
将得到 name
。
看到这个。情况很相似。
当 TypeScript 解析联合类型时,它允许您使用 best common type。我的意思是所有联合元素通用的类型。因为这个选项是最安全的。
让我们检查一下您的工会:
interface FruitBox {
name: string
desc: {
'orange': number;
'banana': number;
}
}
interface IceBox {
name: string
}
interface Vegabox {
name: string
desc: {
'tomato': number;
'potato': number;
}
}
type UnionBox = FruitBox | Vegabox | IceBox;
type AllowedKeys = keyof UnionBox // name
您可能已经注意到 (AllowedKeys
),您只能使用 UnionBox
中的 name
属性。为什么 ?因为name
存在于每个union中。
为了处理它,您可能需要使用 StrictUnion
助手。
// credits goes to
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> =
T extends any
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
完整代码:
interface FruitBox {
name: string
desc: {
'orange': number;
'banana': number;
}
}
interface IceBox {
name: string
}
interface Vegabox {
name: string
desc: {
'tomato': number;
'potato': number;
}
}
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> =
T extends any
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
type UnionBox = StrictUnion<FruitBox | Vegabox | IceBox>;
type AllowedKeys = keyof UnionBox // name
type Ship = Record<string, (description: UnionBox['desc'] | UnionBox['name']) => void>; // ok
const record: Ship = {
foo: (elem) => { }
}
我已经通过 Whosebug 问题进行了搜索,但在我的案例中没有找到所需的答案。
我有
interface FruitBox {
name: string
desc: {
'orange': number;
'banana': number;
}
}
interface IceBox {
name: string
}
interface Vegabox {
name: string
desc: {
'tomato': number;
'potato': number;
}
}
type UnionBox = FruitBox | Vegabox | IceBox;
我正在尝试实现什么
type Ship = Record<string, (description: UnionBox['desc'] | UnionBox['name']) => void>;
我正在尝试将 description
属性 分配给 UnionBox['desc']
类型,如果 desc
参数不存在,则将其分配给 UnionBox['name']
收到下一个错误:
Property 'desc' does not exist on type 'UnionBox'
很高兴得到任何帮助或提示
ps。我知道一定有一些奇怪的算法,只是不确定以哪种方式查看
UnionBox
可以是以下类型之一 - FruitBox
、Vegabox
或 IceBox
。 IceBox
是让 Typescript 不开心的地方——它不包含 属性 desc
。想象一下,有一个 IceBox
类型的对象,然后将它传递给一个函数,该函数将 UnionBox
作为参数,然后使用 属性 desc
- 它会访问一个非现有一个。
I'm trying to assign a description property to a type of UnionBox['desc'] and if desc parameter doesn't exist, then assign it to the UnionBox['name']
我不确定您希望它如何工作,因为在您的示例中描述只是简单地输入为字符串或字符串 - |运算符将简单地创建一个联合。但我想你可以简单地接受 unionBox: UnionBox
作为参数,并在其中添加一个逻辑,如果 desc
不存在,则 unionBox.desc ?? unionBox.name
将得到 name
。
看到这个
当 TypeScript 解析联合类型时,它允许您使用 best common type。我的意思是所有联合元素通用的类型。因为这个选项是最安全的。
让我们检查一下您的工会:
interface FruitBox {
name: string
desc: {
'orange': number;
'banana': number;
}
}
interface IceBox {
name: string
}
interface Vegabox {
name: string
desc: {
'tomato': number;
'potato': number;
}
}
type UnionBox = FruitBox | Vegabox | IceBox;
type AllowedKeys = keyof UnionBox // name
您可能已经注意到 (AllowedKeys
),您只能使用 UnionBox
中的 name
属性。为什么 ?因为name
存在于每个union中。
为了处理它,您可能需要使用 StrictUnion
助手。
// credits goes to
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> =
T extends any
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
完整代码:
interface FruitBox {
name: string
desc: {
'orange': number;
'banana': number;
}
}
interface IceBox {
name: string
}
interface Vegabox {
name: string
desc: {
'tomato': number;
'potato': number;
}
}
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> =
T extends any
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
type UnionBox = StrictUnion<FruitBox | Vegabox | IceBox>;
type AllowedKeys = keyof UnionBox // name
type Ship = Record<string, (description: UnionBox['desc'] | UnionBox['name']) => void>; // ok
const record: Ship = {
foo: (elem) => { }
}