Недавно я обнаружил, что вы можете сделать это в JS:
function foo() {
console.info("FOO");
}
foo.bar = "FOOBAR";
foo(); // logs "FOO"
console.info(foo.bar); // "FOOBAR"
Теперь мой вопрос: как я могу выразить этот тип объекта/функции в машинописном тексте, например. при передаче его в другую функцию в качестве параметра?
Это явно выдает ошибку...
type Foo = () => void;
function test(foo: Foo) {
console.info(foo.bar); // Property 'bar' does not exist on type '() => void'.ts(2339)
}
Есть идеи, кроме как объявить это any
?
Вы можете выразить это с помощью interface
с позывным:
interface FunctionWithBar {
(): void; // <=== Makes this callable, in this case accepting no params
// and returning nothing
bar: string; // Also has a `bar` proprerty of type string
}
function example(f: FunctionWithBar) {
f();
console.info(f.bar);
}
function foo() {
console.info("FOO");
}
foo.bar = "FOOBAR";
example(foo);
Вы можете добавить подпись вызова и свойство bar
к типу Foo
:
type Foo = {
() : void;
bar: string
}
function test(foo: Foo) {
console.info(foo.bar);
}
В качестве альтернативы напишите это как пересечение:
type FooFn = () => void;
type Foo2 = FooFn & {bar: string}
function test2(foo: Foo2) {
console.info(foo.bar);
}
Вы также можете попробовать объединить функцию с пространством имен, более машинописный подход, как показано ниже,
function foo() {
console.info("FOO");
}
namespace foo {
export const bar = "FOOBAR";
}
foo(); // logs "FOO"
console.info(foo.bar); // "FOOBAR"
function test(f: typeof foo) {
console.info(f.bar); // Property 'bar' now exists
}
под этим я подразумеваю, что TS может объединять функцию с пространством имен, что является более «уникальным» для TS.
Почему это «более машинописный» подход? Никогда раньше не использовал пространства имен...