簡體   English   中英

如何將具有計算屬性的對象轉換為類型?

[英]How do I cast an object with computed properties into a type?

我是打字稿的新手,我試圖將字符串轉換為名為Vec2的類型。

我試圖說服打字稿是返回結果parseVec2是一種類型的Vec2 ,但它不會讓我。 即使我將其轉換as Vec2我也會給出相同的錯誤。

interface Vec2 {
    x: number,
    y: number
}

function parseVec2(text: string): Vec2 {
    const [_, arg1, num1, arg2, num2] = text.match(/^([xy]):([^,]+),([xy]):([^,]+)$/)!;

    // error
    return {
        [arg1]: +num1,
        [arg2]: +num2
    };
}

console.log(parseVec2('x:1,y:2'));
console.log(parseVec2('y:3,x:4'));
  • 預期產出
{ x: 1, y: 2 }
{ y: 2, x: 4 }
  • 錯誤
Type '{ [x: string]: number; }' is missing the following properties from type 'Vec2': x, yts(2739)

如果我使用// @ts-ignore來隱藏編譯錯誤,它會完美運行,但我認為這不是正確的方法。

我如何說服打字稿計算屬性arg1arg2xy ,反之亦然?

您有多種選擇,但沒有正確的類型謂詞,您唯一剩下的就是類型斷言。 由於打字稿顯然無法確認arg1arg2在運行時將是xy

您可以直接擦除類型並將其轉換為Vec2

    return {
        [arg1]: +num1,
        [arg2]: +num2
    } as unknown as Vec2;

您可以只投射鍵,仍然與as Vec2類型相同:

    return {
        [arg1 as 'x']: +num1,
        [arg2 as 'y']: +num2
    };

或者使用斷言函數自定義類型謂詞實現正確的運行時檢查:

// with assertion function
function assertVec2(obj: unknown): asserts obj is Vec2 {
    if (typeof obj !== 'object' || obj == null) 
        throw new Error('Vec2 assert fail. Must be an object');
    if (!('x' in obj) || !('y' in obj)) 
        throw new Error('Vec2 assert fail. Missing required "x" and/or "y" fields');
}

function parseVec2(text: string): Vec2 {
    const [_, arg1, num1, arg2, num2] = text.match(/^([xy]):([^,]+),([xy]):([^,]+)$/)!;

    const result = {
        [arg1]: +num1,
        [arg2]: +num2
    }

    assertVec2(result);

    return result;
}

游樂場鏈接

try .. catch塊包裝函數調用,如果出現問題,您將獲得強類型保證和有意義的錯誤消息。

作為 ts 打字細節的旁道,我建議使用更強大的正則表達式。 您當前擁有的將匹配無效結果,例如x:1,x:1y:1,y:1以及無效數值,例如x:foo,y:bar 這可能不是您想要的輸出。 我會改用這樣的東西:

/^(?<_1>[xy]):([+-]?[0-9]+(?:\.[0-9]+)?),(?!\k<_1>)([xy]):([+-]?[0-9]+(?:\.[0-9]+)?)$/

這將解決上述兩個問題以產生一致的輸出。

只需刪除 Vec2 中所需的值。

interface Vec2 {
    x?: number,
    y?: number
}

暫無
暫無

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

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