【问题标题】:Make TypeScript understand that object properties can not be undefined?让 TypeScript 明白对象属性不能未定义?
【发布时间】:2021-08-27 21:11:35
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

标签: javascript typescript types


【解决方案1】:

这是playground link 到一个可行的解决方案。

代码复制如下,带有cmets:

// 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

【讨论】:

  • 谢谢你,它就像我想要的那样工作,你能解释一下对所有这些 Partial 的需求并制作一个函数吗?为什么这能解决问题?
  • 你可以阅读更多关于Partialhere的信息。 Partial 只是让所有成员都是可选的。从技术上讲,您不需要使用它,但知道如何使用它是一件好事。这里的opts 变量定义了所有字段,因为createDefaultOptions 函数保证将定义所有选项。 {...defaultOptions} 将创建一个新对象并从defaultOptions 复制所有成员。然后{...defaultOptions, ...options} 将使用options 对象的属性覆盖其中的任何内容。
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 2012-08-26
相关资源
最近更新 更多