首页 > 解决方案 > 让 TypeScript 明白对象属性不能未定义?

问题描述

在这里问这个是因为不知道如何正确地表达它以便谷歌理解。

我有一个实用函数可以将字符串中的单词大写,作为第二个参数可以传递一个选项对象:

export type Options = {
  onlyFirstWord?: boolean;
  separator?: string;
};

const defaultOptions = {
  onlyFirstWord: false,
  separator: " ",
};

export default function capitalize(
  str: string,
  options: Options = defaultOptions
) {}

所以第二个参数是可选的,因为我已经为它提供了一个默认值,但是如果我在类型中将属性设为可选,它需要我检查这些属性是否未定义,即使它们 100% 永远不会是未定义的, 因为默认值。但是如果我不让它们成为可选的,我将不得不在传递选项对象时输入每个属性,否则会出错。

我知道有很多类似的问题,但是在这种情况下,除了必须放置感叹号或使用可选链接之外,是否没有办法告诉 typescript 这些值永远不会未定义?它不应该自动找出它们永远不会未定义,因为我为其提供了默认值吗?谢谢,如果这是重复的并且已经得到回答,请告诉我。

标签: javascripttypescripttypes

解决方案


这是 一个工作解决方案的游乐场链接。

代码复制如下,并带有注释:

// remove the ?'s from the Options type
type Options = {
  onlyFirstWord: boolean;
  separator: string;
};

const defaultOptions = {
  onlyFirstWord: false,
  separator: "default",
};

// use this function to merge default options with Partial options
const createDefaultOptions = (options: Partial<Options>) => {
    return {...defaultOptions, ...options};
}

// allow the capitalize function to take Partial options
function capitalize(
  str: string,
  options: Partial<Options> = defaultOptions
) {
    // merge the given options with the partial options
    const opts = createDefaultOptions(options);
    // print the result
    console.log(`${str}: ${opts.onlyFirstWord}, ${opts.separator}`);
}

// tests
capitalize('nothing');
capitalize('first', {onlyFirstWord: true});
capitalize('second', {separator: 'j'});
capitalize('both', {onlyFirstWord: true, separator: 'nice'});

输出:

nothing: false, default
first: true, default
second: false, j
both: true, nice

推荐阅读