首页 > 解决方案 > 即使初始化默认参数,TypeScript 也会抱怨 undefined

问题描述

问题是 TypeScript 认为我提供的值UiConfigContext.Provider可能是未定义的。可能是因为?config 可选参数,但我确实提供了默认的{ [Permission.Read]: true}. 我不明白为什么它仍然认为它可能是未定义的。我希望这个函数的参数是可选的,所以任何类似的东西都可以工作:

renderTestComponent();
renderTestComponent({ config: { [Permission.Read]: true });
renderTestComponent({ enterDetails: true });
renderTestComponent({ config: { [Permission.Read]: true }, enterDetails: true );

这是我的代码(TypeScript 游乐场中的复制错误

import React, { createContext } from 'react';

enum Permission {
    Read = 'Read',
    Write = 'Write',
}

type Configuration = Partial<Record<Permission, boolean>>;

export const UiConfigContext = createContext<Configuration | null>(null);

function renderTestComponent(args: {
    config?: Configuration;
    enterDetails?: boolean;
} = {
    config: { [Permission.Read]: true},
    enterDetails: false
}) {
    <UiConfigContext.Provider value={args.config}>
        Test
    </UiConfigContext.Provider>
}

标签: reactjstypescript

解决方案


有两个问题:首先,带有的类型?告诉 Typescript 它可能是undefined. 其次,使用您当前的默认参数,它实际上可能undefined在运行时,这取决于您如何调用它。

第一个问题可以通过删除?.

function renderTestComponent(args: {
    config: Configuration; // <-- removed the ?
    enterDetails: boolean; // <-- removed the ?
} = {
    config: { [Permission.Read]: true},
    enterDetails: false
}) {
    // ...
}

但是,现在它不接受使用部分对象调用它,例如 renderTestComponent({});or renderTestComponent({ enterDetails: true });。在这种情况下,它不会分配默认参数,因为您为它提供了一个值 ( {})。因为config是未定义的,打字稿现在抱怨。

对于第二个问题,我建议使用默认参数和解构如下。在这里,我们为每个属性分配默认值,而不是一次分配整个对象:

function renderTestComponent({
    config = { [Permission.Read]: true },
    enterDetails = false
  } = {}) {
    console.log(config)
} 

renderTestComponent();
renderTestComponent({ config: { [Permission.Read]: true }});
renderTestComponent({ enterDetails: true });
renderTestComponent({ config: { [Permission.Read]: true }, enterDetails: true });

这是一个工作示例:https ://tsplay.dev/m0L6Gm


推荐阅读