打字稿:通过解构缩小类型
Typescript: narrowing types with destructuring
以下代码错误:
type Foo = {
a: true,
b: null,
c: null
} | {
a: false,
b: Error,
c: null
} | {
a: false,
b: null,
c: { prop: number}
}
function getFoo(): Foo {
return { a: false, b: null, c: { prop: 5 } };
}
const { a, b, c } = getFoo();
if (!a && !b) {
console.log(c.prop)
}
给出的错误是:
Object is possibly 'null'.(2531)
这有点道理,因为当 getFoo()
的结果被解构时,较大的 Foo
对象的类型丢失了。
但是,我正在尝试复制 Apollo React 客户端正在做的事情:
const { loading, error, data } = useQuery('...');
if (loading) {
return '..';
}
if (error) {
return '..';
}
return data.foo;
我很难从他们的来源弄清楚他们是如何做到这一点的。
这在 Typescript 中完全可行吗?我最好的猜测是他们的类型可能不是 100% 准确,他们说他们总是 return data
即使他们不这样做。
不可能在 2 个变量之间进行类型保护。您可以在变量 a 和 b 之间创建一个 link 来表示:如果满足 a 的条件 ==> b 是别的东西。对于 Apollo React 客户端,我认为 strictNullChecks 被禁用
以下代码错误:
type Foo = {
a: true,
b: null,
c: null
} | {
a: false,
b: Error,
c: null
} | {
a: false,
b: null,
c: { prop: number}
}
function getFoo(): Foo {
return { a: false, b: null, c: { prop: 5 } };
}
const { a, b, c } = getFoo();
if (!a && !b) {
console.log(c.prop)
}
给出的错误是:
Object is possibly 'null'.(2531)
这有点道理,因为当 getFoo()
的结果被解构时,较大的 Foo
对象的类型丢失了。
但是,我正在尝试复制 Apollo React 客户端正在做的事情:
const { loading, error, data } = useQuery('...');
if (loading) {
return '..';
}
if (error) {
return '..';
}
return data.foo;
我很难从他们的来源弄清楚他们是如何做到这一点的。
这在 Typescript 中完全可行吗?我最好的猜测是他们的类型可能不是 100% 准确,他们说他们总是 return data
即使他们不这样做。
不可能在 2 个变量之间进行类型保护。您可以在变量 a 和 b 之间创建一个 link 来表示:如果满足 a 的条件 ==> b 是别的东西。对于 Apollo React 客户端,我认为 strictNullChecks 被禁用