【问题标题】:Using nullable types in TS在 TS 中使用可为空的类型
【发布时间】:2023-03-30 05:22:02
【问题描述】:

似乎一旦你定义了一个可以为空的类型,你就必须在使用该道具的整个树上撒上它。是不是这样,我只需要在我的代码中添加一些感觉很脏的代码,或者有没有更好的方法来使用 TS 来处理这个问题?

reducers/company.ts 注意到company?companies? 和特色公司了吗?下面:

import ActionTypes from '../actions/ActionTypes';
import { Company } from '../../Interfaces';
import { CompaniesActionType, CompanyActionType } from '../actions/company/CompanyActions';

export interface CompanyState {
    company?: Company;
    companyReceived: boolean;
    companiesReceived: boolean;
    featuredCompaniesReceived?: boolean;
    companies?: Array<Company>;
    featuredCompanies?: Array<Company>;
}

const companyState: CompanyState = {
    company: undefined,
    companyReceived: false,
    companiesReceived: false,
    featuredCompaniesReceived: false,
    companies: undefined,
    featuredCompanies: undefined,
};

export function companies(state: CompanyState = companyState, action: CompaniesActionType): CompanyState {
    switch (action.type) {
        case ActionTypes.COMPANIES_RECEIVED:
            return { ...state, companiesReceived: true, companies: action.companies };
        case ActionTypes.FEATURED_COMPANIES_RECEIVED:
            return { ...state, featuredCompaniesReceived: true, featuredCompanies: action.companies };
        default:
            return state;
    }
}

export function company(state: CompanyState = companyState, action: CompanyActionType): CompanyState {
    switch (action.type) {
        case ActionTypes.COMPANY_RECEIVED:
            return { ...state, companyReceived: true, company: action.company };
        default:
            return state;
    }
}

现在我有一个使用该状态的组件,因为我在减速器中将这些道具定义为可选,所以我也必须使用 HomePage,因为它们将作为道具传递给 HomePage:

HomePage.tsx

export default class HomePage extends Component<{
    featuredCompanies?: Array<Company>,
    companies?: Array<Company>,
    countries?: Array<Country>,
    className: string
}, any> {
    render() {
        return (
            <Main>

在 HomePage 中,树继续呈现 CompanyList:

<CompanyList
className="ft-company-list"
companies={this.props.companies}
countries={this.props.countries} />

因此 CompanyList 还必须将公司和国家/地区定义为它的 React 组件定义的可选参数等等,以用于这两个道具滴入的任何其他子组件......

【问题讨论】:

  • 我不是 100% 确定,但我认为打字稿中的 ? 代表可选,不可为空。这意味着,你可以这样做companies: null,并且你不需要?,除非你计划创建一个对象CompanyState,其中包含除companies之外的所有道具。
  • 不,你不能。如果我删除 ?从 CompanyState 并尝试设置 company: null 或未定义它抱怨它需要一个有效的公司

标签: javascript reactjs typescript


【解决方案1】:

不,如果您确保它是非空类型,那么您可以在标识符后面使用! 后缀。在您的代码中,它将是:

<CompanyList
className="ft-company-list"
companies={this.props.companies!}
countries={this.props.countries!} />

见:https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions

【讨论】:

  • 在某些情况下它可能为空,具体取决于 API 返回给我的动作创建者的内容,那么ensure it a non-null type 是什么意思。我想你是说我必须尽早处理 null 的检查,并确保如果我使用 !,我不会在组件树中进一步发送 null
  • 有趣的是,如果你这样做,你会从 eslint 得到一个禁止的非空断言!
  • 您不需要使用 !一直往下。如果它可以为空,就让它可以为空。如果您确定它不为空,请使用!,如果您不确定,请保持原样 - 您的设置是正确的
  • 你可以在这里忽略这条 esLint 规则:stackoverflow.com/questions/60320613/…
  • 还有另一种解决方法,如果返回空值,可以使用||??设置默认值。
猜你喜欢
  • 1970-01-01
  • 2022-08-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 2020-09-13
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多