我在打字稿项目中有一组对象,我想为其创建类型。每个对象实现三个函数 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') },
}
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
}