我最近从JavaScript切换到TypeScript,感觉真的很棒。在做我的日常工作时,我想知道Promises是如何工作的,在经过简短的Google搜索之后,我发现了这篇可爱的文章:https://softchris.github.io/pages/javascript-promises.html#why。然后,我认为将其转换为TypeScript是一个好习惯。好了,正如您在下面看到的那样,它可以正常工作。我无法解决的一件事是data
,onSuccess
和onFailure
仍然具有any
而不是then<R>(){}
中的泛型。 error
是any
的事实是故意的。
那么有人可以帮我解决这个问题吗?要使用该代码,您可以使用https://stackblitz.com/edit/swear-ts。
非常感谢! :)
type Resolver<T> = (x: T) => void;
type Rejecter = (x: any) => void;
type Factory<T> = (resolve: Resolver<T>, reject?: Rejecter) => void;
type OnSuccessFn<T, R> = (data: T) => R;
type OnFailureFn<R> = (error: any) => R;
class Swear<T = any> {
private data: any;
private resolveWasInvoked = false;
private errorWasHandled = false;
private onSuccess: OnSuccessFn<T, any>;
private onFailure?: OnFailureFn<any>;
constructor(
private factory: Factory<T>,
private error: null | Error = null
) { }
private resolve(data: T): void {
if (!this.error) {
const result = this.onSuccess(data);
if (result) {
this.data = result;
}
this.resolveWasInvoked = true;
}
}
private reject(error: any): void {
if (!this.resolveWasInvoked) {
this.error = error;
if (this.onFailure) {
const result = this.onFailure(error);
if (result) {
this.data = result;
}
this.errorWasHandled = true;
}
}
}
public then<R>(
OnSuccessFn: OnSuccessFn<T, R>,
OnFailureFn?: OnFailureFn<R>
): Swear<R> {
this.onSuccess = OnSuccessFn;
this.onFailure = OnFailureFn;
this.factory(
(data: T): void => this.resolve(data),
(error: any): void => this.reject(error),
)
return new Swear<R>((resolve) => {
resolve(<R>this.data);
}, !this.errorWasHandled ? this.error : null);
}
catch(catchFn: (error: any) => void): void {
if (!this.errorWasHandled && this.error) {
catchFn(this.error);
}
}
}
const swear: Swear<string> = new Swear((resolve, reject) => {
resolve('Hello');
// reject('Ups..');
})
swear
.then(data => data + ' World!')
// .then(data => data.length)
.then(data => console.info(data))
.catch(error => console.error(`Catched: ${error}`));
答案 0 :(得分:0)
做了一些基本的重构来摆脱 any 类型。由于您的函数onSuccess具有两种通用类型,一种用于输入,一种则返回。我向您的班级添加了相同的泛型,以删除大多数 any 用法。此外,错误的打字稿中带有错误类型,您无需使用任何类型。
type Resolver<T> = (x: T) => void;
type Rejecter = (x) => void;
type Factory<T> = (resolve: Resolver<T>, reject?: Rejecter) => void;
type OnSuccessFn<T, R> = (data: T) => R;
type OnFailureFn<R> = (error: Error) => R;
class Swear<T, R> {
private data: R;
private resolveWasInvoked = false;
private errorWasHandled = false;
private onSuccess: OnSuccessFn<T, R>;
private onFailure?: OnFailureFn<R>;
constructor(
private factory: Factory<T>,
private error: null | Error = null
) { }
private resolve(data: T): void {
if (!this.error) {
const result = this.onSuccess(data);
if (result) {
this.data = result;
}
this.resolveWasInvoked = true;
}
}
private reject(error: Error): void {
if (!this.resolveWasInvoked) {
this.error = error;
if (this.onFailure) {
const result = this.onFailure(error);
if (result) {
this.data = result;
}
this.errorWasHandled = true;
}
}
}
public then(
OnSuccessFn: OnSuccessFn<T, R>,
OnFailureFn?: OnFailureFn<R>
) {
this.onSuccess = OnSuccessFn;
this.onFailure = OnFailureFn;
this.factory(
(data: T): void => this.resolve(data),
(error: Error): void => this.reject(error),
)
return new Swear<any, R>((resolve) => {
resolve(<R>this.data);
}, !this.errorWasHandled ? this.error : null);
}
catch(catchFn: (error: Error) => void): void {
if (!this.errorWasHandled && this.error) {
catchFn(this.error);
}
}
}
const swear: Swear<string, void> = new Swear((resolve, reject) => {
resolve('Hello');
// reject('Ups..');
})
swear
.then(data => data + ' World!')
.then(data => console.log(data))
.catch(error => console.error(`Catched: ${error}`));code here