限制打字稿类型定义

时间:2021-07-08 14:40:09

标签: typescript

我有一个 Config 类型定义如下:

type Primitive = string | number | boolean;
type PrimitiveObject = {[key:string] : Primitive};

type Config = {
    baseUrl: string,
    timeout?: number,
    params?: PrimitiveObject,
    [key:string]: Primitive | PrimitiveObject | undefined
};

let conf1:Config = {baseUrl: "https://www.google.com"};

let conf2:Config = {baseUrl: "https://www.google.com", other: 0};

let conf3:Config = {baseUrl: "https://www.ggogle.com", params: {id: 1}};

let conf4:Config = {baseUrl: "https://www.google.com", other: 0, other2: {hello: "world"} };

现在我想将除 (baseUrl, timeout, params) 以外的属性限制为 Primitive,而不是 Primitive | PrimitiveObject。就像 other2 中的 conf4 应该是一个错误。

我尝试了一些方法但失败了

type Config = {
    baseUrl: string,
    timeout?: number,
    params?: PrimitiveObject
} | {
    baseUrl: string
    [key:string]: Primitive
};

let conf1:Config = {baseUrl: "https://www.google.com"};

let conf2:Config = {baseUrl: "https://www.google.com", other: 0};

let conf3:Config = {baseUrl: "https://www.ggogle.com", params: {id: 1}};

// other2 error, which is wanted
let conf4:Config = {baseUrl: "https://www.google.com", other: 0, other2: {hello: "world"} };

let conf5:Config = {other: 2}

// this is also valid, but params is not a PrimitiveObject, I want it throw error too
let conf6:Config = {baseUrl: "https://www.google.com", params: 1}

我是 TypeScript 的新手,有什么建议吗?

1 个答案:

答案 0 :(得分:2)

你可以试试这个方法:

type Config = {
    baseUrl: string,
    timeout?: number,
    params?: PrimitiveObject
} | {
    baseUrl: string
    [key:string]: Primitive | undefined
    params?: never
};

playground link

由于 ts@4.4 设置了 exactOptionalPropertyTypes 标志,因此您可以省略在可索引字段上添加 | undefined

type Config = {
    baseUrl: string,
    timeout?: number,
    params?: PrimitiveObject
} | {
    baseUrl: string
    [key:string]: Primitive
    params?: never
};

playground link

由于 TS playground 中的错误,您必须在 exactOptionalPropertyTypes 弹出窗口中手动切换 TS Config 选项。