簡體   English   中英

如何使用 TypeScript 中的額外屬性初始化數組 object?

[英]How to initialize an array object with extra properties in TypeScript?

我需要創建以下類型的 object:

type ArrayWithA = [number, number, number] & { a: string };

我這樣做如下:

const obj : any = [1, 2, 3];
obj.a = "foo";
const arrayWithA : ArrayWithA = obj as ArrayWithA;

問題:有什么更好的方法來完成這個(即不使用any )?

獎勵問題:什么是初始化 object 類型的好方法: type FuncWithA = ((string)=>void) & { a: string }

使用Object.assign

Object.assign的返回類型只是其 arguments 類型的交集,因此您可以通過列出它們的部分並立即組合來組合這些混合對象,而不是事后添加額外的屬性(這通常需要類型轉換,正如你所注意到的)。

因此,對於您的一些示例,您可能會這樣做:

type ArrayWithA = [number, number, number] & { a: string };

// Try like so:
// The cast is needed as otherwise it will be inferred as number[].
const obj2 = Object.assign([1, 2, 3] as [number, number, number], {a: "foo"}); // obj2 has type: [number, number, number] & { a: string } and is assignable to ArrayWithA.

// Same for functions!
type FuncWithA = ((arg: string) => void) & { a: string };

const f1 = Object.assign((s: string) => {}, {a: "foo"}) // f1 has type: ((s: string) => void) & { a: string } and is assignable to FuncWithA.

游樂場鏈接。

我建議使用Object.assign()TypeScript 的標准庫將其表示為返回所需形式的交集類型。 有一點問題是,要讓編譯器僅僅推斷出數組文字將是確切類型的元組[number, number, number]並不容易。 如果您對readonly [number, number, number]沒問題,那么您可以使用const斷言

type ArrayWithA = readonly [number, number, number] & { a: string };
const arrayWithA: ArrayWithA = Object.assign([1, 2, 3] as const, { a: "foo" });

否則,您可以使用各種技巧:

type ArrayWithA = [number, number, number] & { a: string };

const arr: [number, number, number] = [1, 2, 3]; // annotate extra variable
let arrayWithA: ArrayWithA = Object.assign(arr, { a: "foo" });

// type assertion
arrayWithA = Object.assign([1, 2, 3] as [number, number, number], { a: "foo" });

// helper function
const asTuple = <T extends any[]>(arr: [...T]) => arr;
arrayWithA = Object.assign(asTuple([1, 2, 3]), { a: "foo" });

對於函數,你可以用Object.assign()做同樣的事情:

type FuncWithA = ((x: string) => void) & { a: string }
let funcWithA: FuncWithA = Object.assign(
  (x: string) => console.log(x.toUpperCase()), 
  { a: "foo" }
);

但是您也可以只使用 function 語句並稍后添加屬性,因為 TypeScript 3.1 引入了expando 函數

function func(x: string) {
    console.log(x);
}
func.a = "foo"; // no error
funcWithA = func; // that works

Playground 代碼鏈接

我會 go 類似:

type ArrayWithA = [number, number, number] & { a: string };
namespace ArrayWithA {
  export function of(a: string, ...rest: [number, number, number]): ArrayWithA {
    const o = rest as ArrayWithA;
    o.a = a;
    return o;
  }
}

const arrayWithA = ArrayWithA.of('a', 1, 2, 3);

暫無
暫無

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

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