获取 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 ... */
  }