簡體   English   中英

類型斷言對象字面量打字稿

[英]Type assertion object literal typescript

我試圖創建一個名為對象的對象fields類型的Fields 該對象包含FieldTypes類型的對象,該對象接收泛型並返回另一種類型。

創建對象fields

export const fields = {
  name: {
    label: 'Name',
    type: 'text',
  } as TextType,
};

我的類型文件

export interface Fields {
  [name: string]: FieldTypes;
}

export type Types = 'text' | 'select' | 'checkbox' | 'email' | 'number';

export type ValidationTypes = Yup.MixedSchema | Yup.StringSchema |
  Yup.NumberSchema | Yup.BooleanSchema |
  Yup.DateSchema | Yup.ArraySchema<{}> | Yup.ObjectSchema;

export interface FieldType {
  label: string;
  type: Types;
  initialValue: any;
  validation: ValidationTypes;
  placeholder?: string;
}

export interface TextType extends FieldType { }
export interface EmailType extends FieldType { }
export interface NumberType extends FieldType { }
export interface CheckboxType extends FieldType, CheckboxInterface { }
export interface SelectType extends FieldType {
  options?: Option[];
}

export type FieldTypes = TextType | EmailType | SelectType | CheckboxType | NumberType;

我面臨的問題是,當我將對象name創建為TextType我期望 Typescript 會顯示一個錯誤,例如Object name is missing initialValues and validation properties因為它是在TextType接口上聲明的。

我發現它起作用的唯一方法是定義一個名為FieldName的變量並為其提供字段外的屬性,如下所示:

const NameField: TextType = {
  initialValue: '',
};

像這樣創建我的對象,我收到錯誤Type '{ initialValue: string; }' is missing the following properties from type 'TextType': label, type, validation Type '{ initialValue: string; }' is missing the following properties from type 'TextType': label, type, validation

您錯誤地使用了 TypeScript 的斷言功能。 斷言有一些非常具體的用例,它不應該用於聲明常規的 ol' 變量和類型。

https://basarat.gitbooks.io/typescript/docs/types/type-assertion.html#assertion-thinked-harmful

TypeScript 的類型斷言純粹是你告訴編譯器你比它更了解類型,並且它不應該猜測你。

...

但是,您應該小心使用斷言......編譯器不會保護您不會忘記實際添加您承諾的屬性:

如果您希望對象的字段屬於某種類型,那么您應該顯式聲明它們:

const name: TextType = {
  label: 'Name',
  type: 'text',
};

export const fields: Fields = {
  name
};

這樣,TypeScript 會在您聲明name的行上給您一個錯誤,因為它沒有預期的TextType形狀。

另請注意,您應該將fields聲明為Fields類型,否則 TypeScript 無法理解這是預期的類型。

您的示例是一個很好的展示案例,為什么顯式類型注釋比類型斷言更受歡迎。

我期待打字稿會顯示一個錯誤,比如Object name is missing validation

類型斷言會執行它們自己的兼容性檢查,因此您不會意外地將不兼容的類型(例如const t: string = 3 as string 但是它們比顯式類型更松散,並且會檢查兩個方向的可賦值性:從值/表達式到斷言類型,反之亦然! 如果這些指令之一有效,代碼將被編譯。 一個例子:

const withTypeAssertion = {
  label: 'Name',
  type: 'text',
} as TextType // compiles 😐

已驗證。 { label: string, type: string} (加寬的string文字類型)不可分配/子類型到TextType ,但TextType{ label: string, type: string}的子類型,所以它會編譯! 使用顯式類型,我們會得到想要的錯誤:

const withExplicitType: TextType = {
  label: 'Name',
  type: 'text',
} // error 💣

所以本質上,顯式類型更可取。 例如,您可以使用以下類型注釋fields

export const fields: Fields = {
  name: {
    label: 'Name',
    type: 'text',
  },
};

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM