簡體   English   中英

如何在 TypeScript 中指定類型化的對象文字?

[英]How can I specify a typed object literal in TypeScript?

有沒有辦法直接制作類型化的對象文字?

直接我的意思是不必將它分配給類型注釋的變量。

例如,我知道我可以這樣做:

export interface BaseInfo { value: number; }

export interface MyInfo extends BaseInfo { name: string; }

function testA(): BaseInfo = {
   const result: MyInfo = { value: 1, name: 'Hey!' };
   return result;
}

我也可以這樣做:

function testB(): BaseInfo = {
   return { value: 1, name: 'Hey!' };
}

但我需要的是這樣的:

function testC(): BaseInfo = {
   return { value: 1, name: 'Hey!' }: MyInfo; // <--- doesn't work
}

或者像這樣:

function testD(): BaseInfo = {
   return MyInfo: { value: 1, name: 'Hey!' }; // <--- doesn't work
}

對象文字成員的智能感知由表達式的上下文類型(參見規范的第 4.19 節)提供。

您可以通過多種方式獲取上下文類型。 應用上下文類型的一些最常見的地方是:

  • 帶有類型注釋的變量的初始化器
  • 帶有返回類型注釋的函數或 getter 中的return語句中的表達式
  • 類型斷言表達式 ( <T>expr ) 中的表達式

在您的示例中,您可以使用類型斷言來強制您的對象文字具有上下文類型:

function testB() {
   return <IMyInfo>{ name: 'Hey!' };
}

答案是使用身份功能:

function to<T>(value: T): T { return value; }
const instance = to<MyInfo>({
    value: 1,
    name: 'Hey!',
});

對不必要to函數調用應該沒有性能影響,它應該被 JIT 編譯器優化掉

請記住,接口遵循鴨子類型:如果一個對象看起來與接口匹配,則它確實與接口匹配。

所以

function testB(): IBaseInfo = {
   return { name: 'Hey!' };
}

完全一樣

function testA(): IBaseInfo = {
   var result: IMyInfo = { name: 'Hey!' };
   return result;
}

無論哪種方式,返回的對象看起來都像一個 IMyInfo,所以它是一個 IMyInfo。 函數內部發生的任何事情都不會影響它匹配的接口。

但是,在您的示例中,函數的返回值是 IBaseInfo,因此編譯器和智能感知將假定該對象只是一個 IBaseInfo。 如果你想讓函數的調用者知道返回值是一個IMyInfo,你需要使函數IMyInfo的返回值:

function testB(): IMyInfo = {
   return { name: 'Hey!' };
}

或者簡單地使用類型推斷

function testB() = {
   return { name: 'Hey!' };
}

要真正做到類型安全,有以下方法:

示例界面:

interface IFoo {
  firstName: string;
  lastName: string;
}

指定函數結果類型

function useResultType(): IFoo {
  return {
    firstName: 'mars'
    // compile error, when lastName is missing
    // , lastName: 'xx'
  };
}

返回一個常數

function resultVariable() {
  const result: IFoo = {
    firstName: 'mars'
    // compile error, when lastName is missing
    // , lastName: 'xx'
  };
  return result;
}

使用一個通用的標識函數(注意:rxjs 有一個標識函數)

function ident<T>(value: T): T {
  return value;
}
function identityFunction() {
  return ident<IFoo>({
    firstName: 'mars'
    // compile error, when lastName is missing
    // , lastName: 'xx'
  });
}

當您只使用類型斷言時 - 當您返回任何其他類型時,編譯器不會顯示錯誤(例如,在示例中,我“忘記”了lastName成員)

function asCast() {
  return {
      firstName: 'mars'
    // NO error
  } as IFoo;
}

function cast() {
  return <IFoo>{
      firstName: 'mars'
    // NO error
  };
}

您可以查看Typescript Playground中的示例

你的第一個和第二個例子都失敗了,所以你不能這樣做。 :)

很確定您不必在文字上指定任何類型。 只要你的文字符合接口要求,你就很好。

interface IMyInfo { name: string; }
var asdf = {
   name: "test"
}

var qwer: IMyInfo = asdf;

如果您想要智能感知,您必須執行以下操作:

在此處輸入圖像描述

或者也許這就是你要找的。 Intellisense 在這里工作,至少在操場上。

在此處輸入圖像描述

或者也許這個。 :)

在此處輸入圖像描述

暫無
暫無

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

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