typescript :从联合类型中排除未定义

标签 typescript

有一个自定义类型Options 我创建的(嵌套对象)。我想使用类型 DefaultProperties创建一个包含默认属性的对象。

type Options = {
    id: number,
    text: string | undefined,
    properties: {
        title: string,
        subtitle: string | undefined,
    }
}

type DefaultProperties = Pick<Options, "properties">;

当然默认属性不能是undefined .所以我想排除 undefined从我的工会类型。 为此目的,应该一个像NonNullable<T>这样的内置函数。或 Exclude<T,UnionType> .

我尝试了三种不同的方法来删除 undefined但没有解决方案适用于我的类型。

type Options = {
    id: number,
    text: string | undefined,
    properties: {
        title: string,
        subtitle: string | undefined,
    }
}

type DefaultProperties = Pick<Options, "properties">;


// Try #1: does not work
type Type1 = NonNullable<DefaultProperties>;

// Try #2: does not work
type NotOptional<Type> = {
    [Property in keyof Type]-?: Type[Property];
};
type Type2 = NotOptional<DefaultProperties>;

// Try #3: does not work
type Type3 = Exclude<Options, undefined>;

示例: TypeScript Playground

如何删除所有 undefined s 来 self 所有的类型联合类型?

编辑: 全部undefined s 应该从我的类型中删除。例如:

  • Options['text'] : string (没有更多 undefined )
  • Options['properties']['subtitle'] : string (没有更多 undefined )

稍后我想为此使用类型(例如):

const options : Options = { ... };
const defaults: DefaultProperties= { ... }; // With no undefined

const node : HTMLElement = .... ;
node.innerHTML = options.properties.subtitle !== undefined ? options.properties.subtitle : defaults.properties.subtitle;

defaults.properties.subtitle类型为 string | undefined ,编译器会抛出错误,因为 innerHTML只允许 strings .为此,我想排除 undefined .

最佳答案

您非常接近您的 NotOptional 实用程序类型和 Exclude,问题是您将 DefaultProperties 定义为一个对象properties 属性,但您正试图从 DefaultProperties 中删除 undefined,而不是从其 properties 属性中删除。

在评论中您曾说过您希望 DefaultPropertiesOptions 上的 properties 具有相同的形状。这意味着它的基本形状(在我们尝试删除 undefined 之前)是 Options["properties"]。所以:

type NotOptional<Type> = {
    [Property in keyof Type]: Exclude<Type[Property], undefined>;
};

type DefaultProperties = NotOptional<Options["properties"]>;

测试:

const defaults1: DefaultProperties = {
    title: "foo",
    subtitle: undefined,    // <== Error as desired
};

const defaults2: DefaultProperties = {
    title: "foo",
    subtitle: "something",  // <== No error
};

Playground link

您还可以考虑删除可选性(结合您尝试过的两项操作):

type NotOptional<Type> = {
    [Property in keyof Type]-?: Exclude<Type[Property], undefined>;
};

type DefaultProperties = NotOptional<Options["properties"]>;

测试:

const defaults1: DefaultProperties = {
    title: "foo",
    subtitle: undefined,    // <== Error as desired (wrong type for `subtitle`)
};

const defaults2: DefaultProperties = {  // <== Error as desired (missing `somethingElse`)
    title: "foo",
    subtitle: "something",
};

const defaults3: DefaultProperties = {  // <== No error
    title: "foo",
    subtitle: "something",  // <== No error
    somethingElse: "x",
};

Playground link

关于 typescript :从联合类型中排除未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69581746/

相关文章:

css - 用于 Typescript 的 SVG-React 组件

javascript - 如何使用 NestJS 为特定模块添加路由前缀?

typescript - 可以为 null 或未定义的属性导致 "does not exist"错误

Typescript::条件链接函数

javascript - IE11 Script1002 语法错误。 WebpackJsonP 未定义

typescript - 具有联合类型参数的函数失败,但所有可能的类型组合都通过 - 这是怎么回事?

javascript - Angular 2+ |如何在 NgModule 中使用参数定义路由

typescript - 如何正确使用 Vuex 和 TypeScript?

typescript - 如何使用 VSCode api 打开自定义编辑器

typescript - Typescript 中的再导出类