![](/img/trans.png)
[英]Check whether a property of an object exists and only update another property
[英]Typescript property only allowed if another property exists
假設我有一個 function,如果存在另一個屬性,我只想在其中允許一個屬性。
我試着這樣做,但它返回錯誤Property 'c' does not exist on type 'A'.
type A = {
a?: string;
} & ({ b: string; c?: string } | { b?: string });
const sad = (props: A) => {
const { a, b } = props;
const { c } = props; // Property 'c' does not exist on type 'A'.
return { a, b };
};
有什么解決辦法嗎?
我知道的唯一方法是用戶定義的類型保護,我喜歡將它與聯合類型結合起來
interface CommonProps {
a?: string
b?: string
}
interface SimpleProps extends CommonProps {
kind: "simple"
}
interface ComplexProps extends CommonProps {
kind: "complex"
c?: string
}
type Props = SimpleProps | ComplexProps
function isComplex(arg: Props): arg is ComplexProps {
return arg && arg.kind === 'complex'
}
const sad = (props: Props): any => {
if (isComplex(props)) {
const {a, b, c} = props
// do something
// return something
}
const { a, b } = props
// do something
// return something
}
簡而言之,我為每個可能的屬性組合創建了一個接口。 然后我將它們合並到Props
類型下,並在我的 function 中使用user defined guards
來訪問屬性。
聯合類型只保留兩種類型共有的屬性。 在下面的聯合中,結果類型只有一個屬性: b: string | undefined
b: string | undefined
{ b: string; c?: string } | { b?: string }
下面的代碼將實現你最初的預期,我認為:
type A = {
a?: string;
} & ({ b: string; c?: string; } | { b?: undefined; });
const sad = (props: A) => {
const { a, b } = props;
if (b) {
const { c } = props;
return { a, b, c };
}
return { a, b };
};
在 condition 之外,你不能使用c
,但在 condition 內部, props
的類型已經縮小。 現在b
不能是undefined
,編譯器知道c
。
我只能使用類型和 generics 生成它:
type SelectedOptional<Base, T extends (string | number | symbol) & keyof Base> = {
[Key in keyof Base]: Base[Key];
} & {
[Key in T]: Base[Key];
};
type SelectedNever<Base, T extends string | number | symbol> = {
[Key in keyof Base]: Base[Key];
} & {
[Key in T]?: never;
};
export type Dependant<BaseAttributes, DependantAttributes extends keyof BaseAttributes> =
| SelectedOptional<BaseAttributes, DependantAttributes>
| SelectedNever<BaseAttributes, DependantAttributes>;
您指定包含所有屬性(以及依賴屬性)的基本屬性,然后指定哪 2 個(或更多)相互依賴,如下所示:
這將起作用:
const exampleObject: Dependant<SomeBaseAttributes, 'dependant1' | 'dependant2'> = {
attr1: 1,
attr2: 2,
};
這將失敗,因為您還需要指定屬性“dependant2”:
const exampleObject: Dependant<SomeBaseAttributes, 'dependant1' | 'dependant2'> = {
attr1: 1,
attr2: 2,
dependant1: 3
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.