簡體   English   中英

如何在 Typescript 中擴展匿名類型

[英]How to extend anonymous type in Typescript

當使用匿名類型鏈接typescript中的功能時,例如:

  let array = [{ seed: 2 }, { seed: 3 }];
  array
    .map(i => ({ seed: i.seed, square: i.seed * i.seed }))
    .forEach(i => console.log(`square for ${i.seed} is ${i.square}`));

我需要為地圖函數定義新的匿名類型。 如果我將有多個步驟都生成新屬性,我最終會編寫大量定義代碼來獲取所有屬性。 我可以使用$.extend (或Object.assign ),但那樣我會失去智能感知和強類型。

  array
    .map(i => $.extend(i, { square: i.seed * i.seed }))
    .forEach(i => console.log(`square for ${i.seed} is ${i.square}`));

如何在不重新定義所有屬性的情況下擴展匿名對象,同時保持強類型?

我終於找到了解決辦法。 這可以通過Intersection Types來實現。 這些可以與匿名類型和類一起使用。 在下面的示例中,extend 函數將從每個對象中復制屬性並返回一個交叉類型的對象。 這將減少大量類型定義代碼,而不會丟失智能感知和強類型。

function extend<T, U>(first: T, second: U): T & U {
    let result = <T & U>{};
    for (let id in first) {
        (<any>result)[id] = (<any>first)[id];
    }
    for (let id in second) {
        if (!result.hasOwnProperty(id)) {
            (<any>result)[id] = (<any>second)[id];
        }
    }
    return result;
}

let array = [{ seed: 2 }, { seed: 3 }];

array
    .map(i => extend(i, { square: i.seed * i.seed }))
    .map(i => extend(i, { cube: i.square * i.seed }))
    .forEach(i => console.log(`square for ${i.seed} is ${i.square} and cube is ${i.cube}`));

操場上也一樣

這是在core-js中實現的 fe,它的類型定義返回 Intersection Type:

assign<T, U>(target: T, source: U): T & U;

怎么樣:

interface A {
    seed: number;
}

interface B extends A {
    square: number;
}

let array: A[] = [{ seed: 2 }, { seed: 3 }];
array
    .map<B>(a => { 
        return { seed: a.seed, square: a.seed * a.seed } 
    })
    .forEach(b => console.log("square for ${b.seed} is ${b.square}"));

或(如果您想保持匿名):

let array = [{ seed: 2 }, { seed: 3 }];
array
    .map<{seed: number, square: number}>(a => {
        return { seed: a.seed, square: a.seed * a.seed }
    })
    .forEach(b => console.log("square for ${b.seed} is ${b.square}"));

(在操場上使用)

為了添加一個更容易理解的答案,即如何通過使用交集類型來擴展具有匿名類型的類型,我制作了這個示例來說明它:

interface Animal {
  name: string
}

// With named types:

interface Bear extends Animal {
  honey: boolean
}

function giveHoney(bear: Bear) {
  bear.honey = true;
}

const myBear: Bear = { name: 'Bob', honey: false };
giveHoney(myBear);

// With anonymous types (no need to explicitly define the Bear type):

function giveHoney(bear: Animal & { honey: boolean }) {
  bear.honey = true;
}

const myBear = { name: 'Bob', honey: false };
giveHoney(myBear);

暫無
暫無

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

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