【问题标题】:What is the use case to have an undefined key vs. a not defined key within an object in Typescript?在 Typescript 的对象中具有未定义键与未定义键的用例是什么?
【发布时间】:2020-01-09 09:46:07
【问题描述】:

我正在使用 TypeScript 和这样的正则表达式解析文件名:

import { Filename } from '../models/filename';

const FILENAME_REGEX = /^(?<slug>.*?)(\.(?<language>[a-z]{2}))?(\.|\-(?<region>[A-Z]{2})\.)(?<extension>[a-z]*)$/i;

export const parseFilename = (filename: string): Filename => {
  const result = FILENAME_REGEX.exec(filename);
  if (result?.groups && result.groups['slug'] && result.groups['extension']) {
    return {
      slug: result.groups['slug'],
      language: result.groups['language'],
      region: result.groups['region'],
      extension: result.groups['extension']
    };
  }

  throw new Error("Filename doesn't match pattern");
};

文件名模型如下:

export interface Filename {
  slug: string;
  language?: string;
  region?: string;
  extension: string;
}

我的问题是,如果文件名 page.en.mdregion 组未定义,我将返回一个对象,如 ...

{
  slug: "page",
  language: "en",
  region: undefined,
  extension: "md"
}

.. 有没有一种干净的方法,不需要太多 if 和 else 来获得像这样的对象?:

{
  slug: "page",
  language: "en",
  extension: "md"
}

有一个未定义的键和一个未定义的键的基本原理或用例是什么?

【问题讨论】:

  • 这是一个有趣的问题。我总是通过确保我的代码在未定义时根本不添加键来避免这种情况,但是 javascript 本身有一种方法可以让属性存在但具有未定义的值与根本没有值。不知道你是否可以用 TS 来表达这一点,但我一直在关注答案 =)
  • 缺少键的对象与键具有 undefined 值的对象之间存在明显差异(例如,prop in obj 将是 false 用于前者,true 用于后者),但TypeScript doesn't represent it very well。为了获得最佳结果:不要编写依赖于这种差异的代码

标签: typescript


【解决方案1】:

我不确定你认为什么是“干净的”。如果你想使用函数式编程并且不介意做一点类型断言,你可以这样做:

return (['slug', 'language', 'region', 'extension'] as const).
  filter(k => typeof result.groups?.[k] !== "undefined").reduce(
    (f, k) => (f[k] = result.groups?.[k]! , f),
    {} as Filename);

输出如下:

console.log(parseFilename("foo.html")) 
// {slug: "foo", extension: "html"}
console.log(parseFilename("bar.en.html")) 
// {slug: "bar", language: "en", extension: "html"}
console.log(parseFilename("baz.en-us.html")) 
// {slug: "baz", language: "en", region: "us", extension: "html"}

if/else 换取filter 可能不是一个大赢家,但也许它可以满足您的需求?


但就我个人而言,我只会将 undefined 属性值保留在其中,除非您知道它们确实会在某处造成麻烦。缺失属性和存在但-undefined 属性之间的区别是可以观察到的(例如,prop in obj 对于前一种情况是 false,对于后一种情况是 true),但在许多方面它们是相同的(例如,obj[prop] 的计算结果为 undefined)。 TypeScript doesn't really distinguish between them very consistently,所以即使是表示语言的差异也很困难。所以我建议在检查可选属性时注意不要使用in 等。


好的,希望对您有所帮助;祝你好运!

Playground link to code

【讨论】:

    【解决方案2】:

    我想到的一种方法是在对象字面量中仅定义必需的属性,然后有条件地添加可选属性。

    export interface Filename {
      slug: string;  
      language?: string;
    }
    
    const f: Filename = {
      slug: 'slug'
    };
    
    const lang = undefined;
    if (lang) { 
     f.language = lang;
    }
    

    拥有价值为undefined 的属性与根本没有该属性之间的明显区别在于,在前一种情况下,该属性是由Object.keys() 报告的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-07
      相关资源
      最近更新 更多