簡體   English   中英

TypeScript 中對象字面量的類型定義

[英]Type definition in object literal in TypeScript

在 TypeScript 類中,可以為屬性聲明類型,例如:

class className {
  property: string;
};

如何在對象字面量中聲明屬性的類型?

我嘗試了以下代碼,但無法編譯:

var obj = {
  property: string;
};

我收到以下錯誤:

當前作用域中不存在名稱“字符串”

我做錯了什么還是這是一個錯誤?

你很接近,你只需要更換=: 您可以使用對象類型文字(請參閱規范第 3.5.3 節)或接口。 使用對象類型文字與您所擁有的很接近:

var obj: { property: string; } = { property: "foo" };

但是你也可以使用接口

interface MyObjLayout {
    property: string;
}

var obj: MyObjLayout = { property: "foo" };

2019 年 5 月 15 日更新(改進的代碼模式作為替代方案)

經過多年使用const並從更多功能代碼中受益,我建議在大多數情況下不要使用以下內容。 (在構建對象時,將類型系統強制轉換為特定類型而不是讓它推斷類型通常表明出現了問題)。

相反,我建議盡可能使用const變量,然后將對象作為最后一步:

const id = GetId();
const hasStarted = true;
...
const hasFinished = false;
...
return {hasStarted, hasFinished, id};
  • 這將正確鍵入所有內容,而無需顯式鍵入。
  • 無需重新鍵入字段名稱。
  • 根據我的經驗,這導致了最干凈的代碼。
  • 這允許編譯器提供更多的狀態驗證(例如,如果您在多個位置返回,編譯器將確保始終返回相同類型的對象 - 這鼓勵您在每個位置聲明整個返回值 - 給出一個非常清楚的該值的意圖)。

添加 2020-02-26

如果您確實需要一個可以延遲初始化的類型:將其標記為可空聯合類型(null 或 Type)。 類型系統將阻止您在沒有首先確保它具有值的情況下使用它。

tsconfig.json ,確保啟用嚴格的空檢查:

"strictNullChecks": true

然后使用此模式並允許類型系統保護您免受意外空/未定義訪問:



const state = {
    instance: null as null | ApiService,
    // OR
    // instance: undefined as undefined | ApiService,

};

const useApi = () => {
    // If I try to use it here, the type system requires a safe way to access it

    // Simple lazy-initialization 
    const api = state?.instance ?? (state.instance = new ApiService());
    api.fun();

    // Also here are some ways to only access it if it has value:

    // The 'right' way: Typescript 3.7 required
    state.instance?.fun();

    // Or the old way: If you are stuck before Typescript 3.7
    state.instance && state.instance.fun();

    // Or the long winded way because the above just feels weird
    if (state.instance) { state.instance.fun(); }

    // Or the I came from C and can't check for nulls like they are booleans way
    if (state.instance != null) { state.instance.fun(); }

    // Or the I came from C and can't check for nulls like they are booleans 
    // AND I was told to always use triple === in javascript even with null checks way
    if (state.instance !== null && state.instance !== undefined) { state.instance.fun(); }
};

class ApiService {
    fun() {
        // Do something useful here
    }
}

在 99% 的情況下不要執行以下操作:

2016 年 2 月 10 日更新 - 處理 TSX(感謝 @Josh)

對 TSX 使用as運算符。

var obj = {
    property: null as string
};

一個更長的例子:

var call = {
    hasStarted: null as boolean,
    hasFinished: null as boolean,
    id: null as number,
};

原答案

使用強制轉換運算符使其簡潔(通過將 null 強制轉換為所需類型)。

var obj = {
    property: <string> null
};

一個更長的例子:

var call = {
    hasStarted: <boolean> null,
    hasFinished: <boolean> null,
    id: <number> null,
};

這比有兩個部分(一個聲明類型,第二個聲明默認值)要好得多:

var callVerbose: {
    hasStarted: boolean;
    hasFinished: boolean;
    id: number;
} = {
    hasStarted: null,
    hasFinished: null,
    id: null,
};

我很驚訝沒有人提到這一點,但您可以創建一個名為ObjectLiteral的接口,該接口接受key: value類型string: any

interface ObjectLiteral {
  [key: string]: any;
}

然后你會使用它,就像這樣:

let data: ObjectLiteral = {
  hello: "world",
  goodbye: 1,
  // ...
};

一個額外的好處是,您可以根據需要在任意數量的對象上多次重復使用此界面。

祝你好運。

您可以使用預定義的實用程序類型Record<Keys, Type>

const obj: Record<string, string> = {
  property: "value",
};

它允許為您的對象文字指定鍵:

type Keys = "prop1" | "prop2"

const obj: Record<Keys, string> = {
  prop1: "Hello",
  prop2: "Aloha",
  something: "anything" // TS Error: Type '{ prop1: string; prop2: string; something: string; }' is not assignable to type 'Record<Keys, string>'.
                        //   Object literal may only specify known properties, and 'something' does not exist in type 'Record<Keys, string>'.
};

以及屬性值的類型:

type Keys = "prop1" | "prop2"
type Value = "Hello" | "Aloha"

const obj1: Record<Keys, Value> = {
  prop1: "Hello",
  prop2: "Hey", // TS Error: Type '"Hey"' is not assignable to type 'Value'.
};

如果您嘗試編寫類型注釋,則語法為:

var x: { property: string; } = { property: 'hello' };

如果你想寫一個對象字面量,語法是:

var x = { property: 'hello' };

您的代碼試圖在值位置使用類型名稱。

如果您嘗試將類型添加到解構的對象文字中,例如在函數的參數中,語法是:

function foo({ bar, baz }: { bar: boolean, baz: string }) {
  // ...
}

foo({ bar: true, baz: 'lorem ipsum' });

在 TypeScript 中,如果我們聲明對象,那么我們將使用以下語法:

[access modifier] variable name : { /* structure of object */ }

例如:

private Object:{ Key1: string, Key2: number }
// Use ..

const Per = {
  name: 'HAMZA',
  age: 20,
  coords: {
    tele: '09',
    lan: '190'
  },
  setAge(age: Number): void {
    this.age = age;
  },
  getAge(): Number {
    return age;
  }
};
const { age, name }: { age: Number; name: String } = Per;
const {
  coords: { tele, lan }
}: { coords: { tele: String; lan: String } } = Per;

console.log(Per.getAge());

在您的代碼中:

var obj = {
  myProp: string;
};

您實際上是在創建一個對象文字並將變量字符串分配給屬性 myProp。 盡管非常糟糕的做法,這實際上是有效的 TS 代碼(不要使用它!):

var string = 'A string';

var obj = {
  property: string
};

但是,您想要的是鍵入對象文字。 這可以通過多種方式實現:

界面:

interface myObj {
    property: string;
}

var obj: myObj = { property: "My string" };

類型別名:

type myObjType = {
    property: string
};

var obj: myObjType = { property: "My string" };

對象類型文字:

var obj: { property: string; } = { property: "Mystring" };

這就是我在 2021 年要做的事情:

const sm = {
  currentCacheName: '' as string,
  badSWTimer: 0 as number,
  reg: {} as ServiceWorkerRegistration,
  quantum: null as number | null
}

這不僅僅是一個值轉換,而且與接口定義的工作方式相同,對於對象屬性來說。

  1. 使用 type 關鍵字創建類型
type ObjType = {
  property: string;
}

然后您可以使用它來綁定您的對象以僅接受此類型,如下所示。

const obj: ObjType = {
property: "TypeScript"
}

使用 DRY 將對象文字轉換為類型

做就是了:

const myObject = {
   hello: 'how are you',
   hey: 'i am fine thank you'
}
type myObjectType = keyof typeof MyObject

任務完成!

謹防。 對某些人來說似乎很明顯,但類型聲明:

const foo: TypeName = {}

是不是比用鑄造相同as

const foo = {} as TypeName

盡管建議在其他答案上使用它。

例子:

謝謝,類型安全!:

const foo: { [K in 'open' | 'closed']: string } = {}
// ERROR: TS2739: Type '{}' is missing the following properties from type '{ open: string; closed: string; }': open, closed

再見,類型安全!:

const foo = {} as { [K in 'open' | 'closed']: string }
// No error

只是為了擴展@RickLove 的回復......

這很好用,因為您只需要定義無法推斷的類型:

const initialState = { 
   user: undefined as User | undefined, 
   userLoading: false
}; 

它轉換為這個 js 代碼:

const initialState = { 
   user: undefined, 
   userLoading: false
};  

如果你需要將它提取到一個類型中,你可以這樣做:

export type InitState = typeof initialState;

暫無
暫無

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

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