在解构赋值之前声明对象 属性 类型
Declaring object property types before destructuring assignment
假设有一个函数 returns 一个对象,其 属性 类型可以被推断或明确提供:
const myFn = (arg: number) => {
return {
a: 1 + arg,
b: 'b' + arg,
c: (() => { return arg + 'c'})()
}
}
然后我们可以解构返回的对象并分配给新变量:
const { a, b, c } = myFn(10);
console.log('used once', a, b, c);
一切都很好,花花公子。现在让我们假设我们稍后需要重新分配给那些相同的变量,更具体地说是在 switch 语句中。为了防止 Cannot redeclare block-scoped variable 'xyz'. ts(2451)
我们将利用 assignment without declaration 并像这样进行:
let my_a, my_b, my_c;
switch (true) {
case Math.random() < 0.5:
({a: my_a, b: my_b, c: my_c} = myFn(Math.random()));
console.log('called at one point', my_a, my_b, my_c);
default:
({a: my_a, b: my_b, c: my_c} = myFn(Math.random()));
console.log('called at another point', my_a, my_b, my_c);
}
那么问题是,当我知道 declare/extract my_a
、my_b
等类型时,我知道它们将是什么并且不想手动把它们打出来? Here's a playground snippet.
详细说明
我正在寻找的是一种在我使用
初始化变量时声明类型的方法
let my_a, my_b, my_c;
根据我对myFn
签名的了解,以防止
Variable 'my_a' implicitly has an 'any' type,
but a better type may be inferred from usage. ts(7043)
您可以声明一个接口并将您的开关逻辑放在匿名箭头函数中:
interface Alphabet {
a: number,
b: string,
c: string,
}
const myFn = (arg: number): Alphabet => {
return {
a: 1 + arg,
b: 'b' + arg,
c: (() => { return arg + 'c'})()
}
}
let my_a, my_b, my_c;
switch (true) {
case Math.random() < 0.5:
() => {
const {a: my_a, b: my_b, c: my_c}: Alphabet = myFn(Math.random());
console.log('called at one point', my_a, my_b, my_c);
}
default:
() => {
const {a: my_a, b: my_b, c: my_c}: Alphabet = myFn(Math.random());
console.log('called at one point', my_a, my_b, my_c);
}
}
如果您只想提前显式键入 my_*
变量,那么您可以通过钻取函数的 return 类型来实现。
let my_a: ReturnType<typeof myFn>['a'],
my_b: ReturnType<typeof myFn>['b'],
my_c: ReturnType<typeof myFn>['c'];
typeof myFn
从 myFn
获取函数类型,因此类型系统可以使用它。 ReturnType<...>
将获得函数 returns 的类型。最后,['a']
将从 return 类型中获取 a
属性。
但这并不是真正需要的。您的 playground 片段可以正确推断出所有内容,并且不会引发类型错误。所以我会考虑这是否真的有必要。
假设有一个函数 returns 一个对象,其 属性 类型可以被推断或明确提供:
const myFn = (arg: number) => {
return {
a: 1 + arg,
b: 'b' + arg,
c: (() => { return arg + 'c'})()
}
}
然后我们可以解构返回的对象并分配给新变量:
const { a, b, c } = myFn(10);
console.log('used once', a, b, c);
一切都很好,花花公子。现在让我们假设我们稍后需要重新分配给那些相同的变量,更具体地说是在 switch 语句中。为了防止 Cannot redeclare block-scoped variable 'xyz'. ts(2451)
我们将利用 assignment without declaration 并像这样进行:
let my_a, my_b, my_c;
switch (true) {
case Math.random() < 0.5:
({a: my_a, b: my_b, c: my_c} = myFn(Math.random()));
console.log('called at one point', my_a, my_b, my_c);
default:
({a: my_a, b: my_b, c: my_c} = myFn(Math.random()));
console.log('called at another point', my_a, my_b, my_c);
}
那么问题是,当我知道 declare/extract my_a
、my_b
等类型时,我知道它们将是什么并且不想手动把它们打出来? Here's a playground snippet.
详细说明
我正在寻找的是一种在我使用
初始化变量时声明类型的方法let my_a, my_b, my_c;
根据我对myFn
签名的了解,以防止
Variable 'my_a' implicitly has an 'any' type,
but a better type may be inferred from usage. ts(7043)
您可以声明一个接口并将您的开关逻辑放在匿名箭头函数中:
interface Alphabet {
a: number,
b: string,
c: string,
}
const myFn = (arg: number): Alphabet => {
return {
a: 1 + arg,
b: 'b' + arg,
c: (() => { return arg + 'c'})()
}
}
let my_a, my_b, my_c;
switch (true) {
case Math.random() < 0.5:
() => {
const {a: my_a, b: my_b, c: my_c}: Alphabet = myFn(Math.random());
console.log('called at one point', my_a, my_b, my_c);
}
default:
() => {
const {a: my_a, b: my_b, c: my_c}: Alphabet = myFn(Math.random());
console.log('called at one point', my_a, my_b, my_c);
}
}
如果您只想提前显式键入 my_*
变量,那么您可以通过钻取函数的 return 类型来实现。
let my_a: ReturnType<typeof myFn>['a'],
my_b: ReturnType<typeof myFn>['b'],
my_c: ReturnType<typeof myFn>['c'];
typeof myFn
从 myFn
获取函数类型,因此类型系统可以使用它。 ReturnType<...>
将获得函数 returns 的类型。最后,['a']
将从 return 类型中获取 a
属性。
但这并不是真正需要的。您的 playground 片段可以正确推断出所有内容,并且不会引发类型错误。所以我会考虑这是否真的有必要。