以下是我的界面:

export type alphaColorProcessing = (opacity: number) => string | string[];

export interface welcomeMapping {
  [key: string]: alphaColorProcessing | string;
}
export interface IPalette {
  [key: string]: string | string[] | alphaColorProcessing | welcomeMapping;
}
export interface IThemeContext {
  theme: string;
  palette: IPalette;
  setTheme?: (theme: string) => void;
}

export interface IThemeState extends IThemeContext {
  isDark: Boolean;
}

export interface IAppState {
  loading: boolean;
  themeState: IThemeState;
}

export interface IAppProps {
  setTheme?: (theme: string) => void;
}

我在App个组件中使用这些:

enter image description here

但我有一个问题:当在this上声明一个方法时,在构造函数中,据我所知,它与IAppState无关.所以我的问题是,我如何声明/使用一个接口来重新传递既不到State,也不到Props的方法?我需要为组件的this设置方法/属性.

netInfoSubscription, setTheme-是我感兴趣的.

以下是代码:

export default class App extends React.PureComponent<{},IAppState>  {
  showedForce = false;

  showedBadIP = false;

  constructor(props) {
    super(props);
    this.setTheme = (theme:string) => {
      this.setState((state) => ({
        themeState: {
          ...state.themeState,
          theme,
          isDark: theme === 'dark',
          palette: Palette,
        },
      }));
    };
    this.state = {
      loading: true,
      themeState: {
        theme: 'light',
        isDark: false,
        palette: Palette,
        setTheme: this.setTheme,
      },
    };
  }

  componentDidMount() {
    NetInfo.configure({
      reachabilityUrl: 'https://www.cisco.com/',
    });
    this.netInfoSubscription = NetInfo.addEventListener((state) => {
      handleConnectionStatus(state.isConnected);
    });
  }

  render() {
    const { themeState, loading } = this.state;
    if (loading) return null;
    return (
      <Provider store={ Store }>
        <AppearanceProvider>
          <SafeAreaProvider>
            <Root>
              <ThemeContext.Provider value={ themeState }>
                <Navigation />
                <FingerprintModal />
              </ThemeContext.Provider>
            </Root>
          </SafeAreaProvider>
        </AppearanceProvider>
      </Provider>
    );
  }
}

推荐答案

你问过两个相关的问题:setThemenetInfoSubscription.

你有几个 Select :

方法语法

你的setTheme是一个方法,所以你可以把它写成一个,然后在构造函数中使用bind:

export default class App extends React.PureComponent<{},IAppState>  {
    constructor(props) {
        // ...
        this.setTheme = this.setTheme.bind(this);
        // ...
    }

    setTheme(theme: string) {
        // ...
    }
}

这样做的一个优点是setThemeApp.prototype上,这有时有助于单元测试(可以模拟).

这适用于setTheme人,但不适用于netInfoSubscription人;为此,您需要以下其他选项之一.

属性声明(包括方法)

您可以将setTheme写为属性(当然,netInfoSubscription也是属性):

export default class App extends React.PureComponent<{},IAppState>  {
    setTheme = (theme: string) => {
        // ...
    };
    netInfoSubscription?: SubscriptionType;
    // Or:
    netInfoSubscription: SubscriptionType | null = null;
}

对于setTheme,因为这是一个箭头函数,所以不需要绑定.它关闭的上下文中有this个引用正在构造的实例.

对于netInfoSubscription,因为我们在实例构建期间没有它的值,所以有两个选项:

  • 使用?表示该属性是可选的.
  • 使用值为null的联合类型,直到/除非我们有订阅.

请注意,这两种情况中的任何一种都意味着netInfoSubscription可以是代码中的undefined(或null).对于you不知道(但TypeScript不知道)的地方,可以将其抓取到一个局部常量并进行断言:

someMethod() {
    // If we *know* (from the logic) that we have the subscription now
    const { netInfoSubscription } = this;
    assertNotNullish(netInfoSubscription);
    // ...here you can use `netInfoSubscription`'s value, and TypeScript will understand
    // that we now know it has one
    // ...
}

assertNotNullish是我的标准实用程序函数之一,如下所示:

const assertNotNullish: <T>(value: T | undefined | null) => asserts value is T = (value) => {
    if (value == null) { // Checks `null` and `undefined`
        throw new Error(`Expected value to be non-nullish`);
    }
};

Playground link

Note:could只使用non-null assertion operator,但我不会.使用assertNotNull这样的东西可以判断你所断言的是真的.使用非空断言运算符则不会,它只会告诉TypeScript假定断言为真.

接口

您可以定义一个接口:

interface AppInstanceMembers {
    setTheme: (theme: string) => void;
    netInfoSubscription?: SubscriptionType;
    // ...
}
// ...
export default class App extends React.PureComponent<{},IAppState> & AppInstanceMembers {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^
    constructor(props) {
        // ...
        this.setTheme = (theme/* You don't have to repeat the type here*/) => {
            // ...
        };
        // ...
    }
    // ...
}

这告诉TypeScript在App上预期setTheme(可能是netInfoSubscription)(这在构造函数中是可以满足的).但这确实意味着你必须重复setTheme的某些部分.

如前所示,在you从逻辑(但TypeScript不知道)知道netInfoSubscription不会为空的地方,可以使用assertNotNullish.

Typescript相关问答推荐

如何将http上下文附加到angular中翻译模块发送的请求

类型脚本中的Gnomeshell 扩展.如何导入.ts文件

React Hook中基于动态收件箱定义和断言回报类型

如何使类型只能有来自另一个类型的键,但键可以有一个新值,新键应该抛出一个错误

需要使用相同组件重新加载路由变更数据—React TSX

使某些类型的字段变为可选字段'

将props传递给子组件并有条件地呈现它''

如何修复正在处理类型但与函数一起使用时不处理的类型脚本类型

如何使我的函数专门针对联合标记?

TypeError:正文不可用-NextJS服务器操作POST

使用数组作为类型中允许的键的列表

如果数组使用Reaction-Hook-Form更改,则重新呈现表单

为什么Typescript不能推断类型?

不带其他属性的精确函数返回类型

将带有样式的Reaction组件导入到Pages文件夹时不起作用

为什么我的函数arg得到类型为Never?

为什么在这种情况下,打字脚本泛型无法正确自动完成?

创建一个函数,该函数返回一个行为方式与传入函数相同的函数

完全在类型系统中构建的东西意味着什么?

在ts中获取级联子K类型?