我正在试图弄清楚如何根据参数在promises上使用typeguards。
function request({ logic }: { logic: boolean }) {
return new Promise((resolve, reject) => {
if (l)
resolve("something");
resolve(1);
});
}
request({ logic: true }).then(a => {
a.length
})
在这个例子中,我想确保'a'=='字符串'的类型。我尝试在request
中编写一些类型保护措施,但结果却丢失了。我不知道这只是打字稿的限制,还是我只需要做一些智能型铸造或什么。
这是我实际尝试做的一个玩具示例,即进行异步调用,其结果根据某些参数略有不同。而且我不愿意做另一个功能只是为了覆盖一个改变的返回类型
答案 0 :(得分:3)
打字稿函数重载到救援:
function request(logic: true): Promise<string>;
function request(logic: false): Promise<number>;
function request(logic: boolean) {
return new Promise((resolve, reject) => {
if (logic)
resolve("something");
resolve(1);
});
}
request(true).then(a => {
console.log(a.length); //<-- knows that a is a string
});
request(false).then(a => {
console.log(a.length); //<-- error: prop 'length' does not exist on number
});
Typeguards旨在用于if
语句。
修改强>
你会感到惊讶! Typescript也支持基于字段的重载区别!请检查以下代码:
function request(opts: { logic: true }): Promise<string>;
function request(opts: { logic: false }): Promise<number>;
function request(opts: { logic: boolean }) {
return new Promise((resolve, reject) => {
if (opts.logic)
resolve("something");
resolve(1);
});
}
request({ logic: true }).then(a => {
console.log(a.length); //<-- knows that a is a string
});
request({ logic: false }).then(a => {
console.log(a.length); //<-- error: prop length cannot be found on type number
});
编辑
通过一点通用魔法,您可以实现所需的行为。这样,只有logic
字段才能从调用者的角度出发。缺点是,即使opts.logic
函数实现中的request
,您也会失去类型检查。
function request<T extends { logic: true }>(opts: T): Promise<string>;
function request<T extends { logic: false }>(opts: T): Promise<number>;
function request(opts: any) {
return new Promise((resolve, reject) => {
if (opts.logic)
resolve("something");
resolve(1);
console.log(opts.anything);
});
}
request({ logic: true, foo: 'bar' }).then(a => {
console.log(a.length); //<-- knows that a is a string
});
request({ logic: false, foo: 'baz' }).then(a => {
console.log(a.length); //<-- error: prop length cannot be found on type number
});
答案 1 :(得分:-1)
下一个是正确的重载(应该添加类型):
function request(logic: boolean): Promise<string>;
function request(logic: boolean): Promise<number>;
function request(logic: boolean): Promise<any>;
function request(logic: boolean) {
return new Promise((resolve, reject) => {
if (logic)
resolve("something");
resolve(1);
});
}
request(true).then((a) => {
console.log(a.length); //<-- knows that a is a string
});
request(false).then((a) => {
console.log(a.length); //<-- error: prop 'length' does not exist on number
});