获取 React 并发承诺包装器以继承返回的接口对象
Getting React concurrent promise wrapper to inherit returned interface object
我正在 React 中试验并发模式和悬念,当我尝试将一些模拟数据从父组件钻取到子组件时遇到类型错误,因为我的 promise 包装器本身并不知道类型正在阅读。我收到的错误消息是:
TS2739: Type '{ data: any; }' is missing the following properties from
type 'MockData': title, name, address, city
我如何才能让我的承诺包装器知道得到 returned 的类型而不明确说明 export const promiseWrapper = (promise: Promise<MockData>): PromiseWrapper => {...
因为我想将这个承诺包装器用于其他提取可以return其他接口吗?谢谢!
sampleComponent.tsx:
import * as React from 'react';
import api, { MockData } from 'api/api';
const resource = api.getMockData();
const SampleComponent: React.FC = () => {
const mockData = resource.mockData.read();
return (
<ChildComponent mockData={mockData} /> // type error received here
);
};
interface ChildProps {
mockData: MockData;
}
const ChildComponent: React.FC<ChildProps> = ({ mockData }) => (
<div>
<h1>{mockData.title}</h1>
<h1>{mockData.name}</h1>
<h1>{mockData.address}</h1>
<h1>{mockData.city}</h1>
</div>
);
api.ts:
import { PromiseWrapper, promiseWrapper } from './promiseWrapper';
export interface Resource {
[key: string]: PromiseWrapper;
}
export interface MockData {
title: string;
name: string;
address: string;
city: string;
}
const mockData = {
title: 'this is a title',
name: 'John Smith',
address: '102 Street',
city: 'Pittsburgh',
};
const mockDataPromise = (): Promise<{ data: MockData }> => new Promise((resolve) => {
setTimeout(() => {
resolve({
data: mockData,
});
}, 1000);
});
const getMockData = (): Resource => {
const getMockDataPromise = mockDataPromise();
return {
mockData: promiseWrapper(getMockDataPromise),
};
};
export default {
getMockData,
};
promiseWrapper.ts:
export interface PromiseWrapper {
read(): {
data: any;
};
}
export const promiseWrapper = (promise: Promise<any>): PromiseWrapper => {
let status = 'pending';
let result: object;
const suspender = promise.then(
(r) => {
status = 'success';
result = r;
},
(e) => {
status = 'error';
result = e;
},
);
return {
// @ts-ignore
// eslint-disable-next-line consistent-return
read() {
if (status === 'pending') {
throw suspender;
} else if (status === 'error') {
throw result;
} else if (status === 'success') {
return result;
}
},
};
};
export interface PromiseWrapper<T> {
read(): { data: T }
}
export function promiseWrapper<T>(promise: Promise<{ data: T }>): PromiseWrapper<T> {
let status = 'pending'
let result: { data: T }
/* rest of the function remains unchanged ... */
}
我正在 React 中试验并发模式和悬念,当我尝试将一些模拟数据从父组件钻取到子组件时遇到类型错误,因为我的 promise 包装器本身并不知道类型正在阅读。我收到的错误消息是:
TS2739: Type '{ data: any; }' is missing the following properties from type 'MockData': title, name, address, city
我如何才能让我的承诺包装器知道得到 returned 的类型而不明确说明 export const promiseWrapper = (promise: Promise<MockData>): PromiseWrapper => {...
因为我想将这个承诺包装器用于其他提取可以return其他接口吗?谢谢!
sampleComponent.tsx:
import * as React from 'react';
import api, { MockData } from 'api/api';
const resource = api.getMockData();
const SampleComponent: React.FC = () => {
const mockData = resource.mockData.read();
return (
<ChildComponent mockData={mockData} /> // type error received here
);
};
interface ChildProps {
mockData: MockData;
}
const ChildComponent: React.FC<ChildProps> = ({ mockData }) => (
<div>
<h1>{mockData.title}</h1>
<h1>{mockData.name}</h1>
<h1>{mockData.address}</h1>
<h1>{mockData.city}</h1>
</div>
);
api.ts:
import { PromiseWrapper, promiseWrapper } from './promiseWrapper';
export interface Resource {
[key: string]: PromiseWrapper;
}
export interface MockData {
title: string;
name: string;
address: string;
city: string;
}
const mockData = {
title: 'this is a title',
name: 'John Smith',
address: '102 Street',
city: 'Pittsburgh',
};
const mockDataPromise = (): Promise<{ data: MockData }> => new Promise((resolve) => {
setTimeout(() => {
resolve({
data: mockData,
});
}, 1000);
});
const getMockData = (): Resource => {
const getMockDataPromise = mockDataPromise();
return {
mockData: promiseWrapper(getMockDataPromise),
};
};
export default {
getMockData,
};
promiseWrapper.ts:
export interface PromiseWrapper {
read(): {
data: any;
};
}
export const promiseWrapper = (promise: Promise<any>): PromiseWrapper => {
let status = 'pending';
let result: object;
const suspender = promise.then(
(r) => {
status = 'success';
result = r;
},
(e) => {
status = 'error';
result = e;
},
);
return {
// @ts-ignore
// eslint-disable-next-line consistent-return
read() {
if (status === 'pending') {
throw suspender;
} else if (status === 'error') {
throw result;
} else if (status === 'success') {
return result;
}
},
};
};
export interface PromiseWrapper<T> {
read(): { data: T }
}
export function promiseWrapper<T>(promise: Promise<{ data: T }>): PromiseWrapper<T> {
let status = 'pending'
let result: { data: T }
/* rest of the function remains unchanged ... */
}