具有可选功能的对象的打字稿类型

问题描述 投票:0回答:1

我在打字稿项目中有一组对象,我想为其创建类型。每个对象实现三个函数 a、b 和 c 的某种组合。我想创建一个类型,这样当我创建这种类型的对象时,您只能实现函数 a、b 和 c。使用时根据具体实现只能调用实际实现的函数

具有三个功能的接口不起作用,因为必须实现每个功能。如果我将函数设置为可选,那么这可以工作,但是当我实际使用对象时,我可以调用 a、b 或 c,无论它们是否已实现

考虑以下示例,我希望以下所有示例共享一个类型,允许它们实现函数 a、b 和 c 的任意组合。但使用时就受到限制,只能使用他们实际实现的功能

例如

exampleOne.a();
还好
exampleOne.c();
将是一个编译时错误

const exampleOne = {
  a: () => { console.log('a') },
  b: () => { console.log('b') },
}

const exampleTwo = {
  c: () => { console.log('c') },
}

const exampleThree = {
  b: () => { console.log('b') },
  c: () => { console.log('c') },
}
typescript types typescript-typings
1个回答
0
投票

对于问题中的具体示例,您可能正在寻找一种具有可选函数与新的

satisfies
运算符相结合的类型。这是类型:

interface Example {
    a?: () => void;
    b?: () => void;
    c?: () => void;
}

然后将其与这些示例对象一起使用:

const exampleOne = {
    a: () => {
        console.log("a");
    },
    b: () => {
        console.log("b");
    },
} satisfies Example;

exampleOne.a(); // No error
exampleOne.b(); // No error
exampleOne.c(); // Error

const exampleTwo = {
    c: () => {
        console.log("c");
    },
} satisfies Example;

exampleTwo.a(); // Error
exampleTwo.b(); // Error
exampleTwo.c(); // No error

const exampleThree = {
    b: () => {
        console.log("b");
    },
    c: () => {
        console.log("c");
    },
} satisfies Example;

exampleThree.a(); // Error
exampleThree.b(); // No error
exampleThree.c(); // No error

这是可行的,因为

exampleOne
等的类型是 Example
子类型
,它消除了所提供函数的可选性。

这只适用于具有该子类型的情况。如果你只有

Example
,你需要首先证明函数存在:

function example(e: Example) {
    // Calling one of the functions using optional chaining, which will call the
    // function if it exists, skip it (no call, no error) if not
    e.a?.();

    // Calling one of the functions by explicitly checking if it's there
    if (e.b) {
        e.b();
    }

    // You can't just call the function, because it's not clear whether it exists
    e.c(); // <== Error
}

拥有上述所有设施的游乐场

© www.soinside.com 2019 - 2024. All rights reserved.