[英]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
來隱藏編譯錯誤,它會完美運行,但我認為這不是正確的方法。
我如何說服打字稿計算屬性arg1
和arg2
是x
和y
,反之亦然?
您有多種選擇,但沒有正確的類型謂詞,您唯一剩下的就是類型斷言。 由於打字稿顯然無法確認arg1
, arg2
在運行時將是x
和y
。
您可以直接擦除類型並將其轉換為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:1
和y: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.