diff --git a/docs/en/development/ui-extensions.md b/docs/en/development/ui-extensions.md
index 1b3a22af3d..7f0821550f 100644
--- a/docs/en/development/ui-extensions.md
+++ b/docs/en/development/ui-extensions.md
@@ -107,3 +107,37 @@ binder.bind("repo.avatar", GitAvatar, (props) => props.type === "git");
```javascript
```
+
+### Typings
+
+Both extension points and extensions can share a common typescript type to define the contract between them.
+This includes the `name`, the type of `props` passed to the predicate and what `type` the extensions themselves can be.
+
+Example:
+```typescript
+ type CalculatorExtensionPoint = ExtensionPointDefinition<"extension.calculator", (input: number[]) => number, undefined>;
+
+ const sum = (a: number, b: number) => a + b;
+ binder.bind("extension.calculator", (input: number[]) => input.reduce(sum, 0));
+ const calculator = binder.getExtension("extension.calculator");
+ const result = calculator([1, 2, 3]);
+```
+
+In this example, we use the base type `ExtensionPointDefinition` to declare a new extension point.
+
+As we do not need a predicate, we can define the `props` type parameter as `undefined`. This allows us to skip the `props` parameter in the
+`getExtension` method and the `predicate` parameter in the `bind` method.
+
+When using `bind` to define an extension or `getExtension` to retrieve an extension, we can pass the new type as a type parameter.
+By doing this, we allow typescript to help us with type-checks and offer us type-completion.
+
+Negative Example:
+```typescript
+ type CalculatorExtensionPoint = ExtensionPointDefinition<"extension.calculator", (input: number[]) => number, undefined>;
+
+ const sum = (a: number, b: number) => a + b;
+ binder.bind("extension.calculato", (input: number[]) => input.reduce(sum, 0));
+```
+
+This code for example, would lead to a compile time type error because we made a typo in the `name` of the extension when binding it.
+If we had used the `bind` method without the type parameter, we would not have gotten an error but run into problems at runtime.
diff --git a/gradle/changelog/extension-point-typings.yaml b/gradle/changelog/extension-point-typings.yaml
new file mode 100644
index 0000000000..0322582413
--- /dev/null
+++ b/gradle/changelog/extension-point-typings.yaml
@@ -0,0 +1,2 @@
+- type: added
+ description: Implement api for extension point typings ([#1638](https://github.com/scm-manager/scm-manager/pull/1638))
diff --git a/scm-plugins/scm-git-plugin/package.json b/scm-plugins/scm-git-plugin/package.json
index a2aab63ff7..3396f49177 100644
--- a/scm-plugins/scm-git-plugin/package.json
+++ b/scm-plugins/scm-git-plugin/package.json
@@ -14,7 +14,7 @@
"@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT"
},
"devDependencies": {
- "@scm-manager/babel-preset": "^2.11.1",
+ "@scm-manager/babel-preset": "^2.12.0",
"@scm-manager/eslint-config": "^2.11.1",
"@scm-manager/jest-preset": "^2.12.7",
"@scm-manager/plugin-scripts": "^1.0.1",
diff --git a/scm-plugins/scm-hg-plugin/package.json b/scm-plugins/scm-hg-plugin/package.json
index 10c26de915..7b3c149a11 100644
--- a/scm-plugins/scm-hg-plugin/package.json
+++ b/scm-plugins/scm-hg-plugin/package.json
@@ -13,7 +13,7 @@
"@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT"
},
"devDependencies": {
- "@scm-manager/babel-preset": "^2.11.1",
+ "@scm-manager/babel-preset": "^2.12.0",
"@scm-manager/eslint-config": "^2.11.1",
"@scm-manager/jest-preset": "^2.12.7",
"@scm-manager/plugin-scripts": "^1.0.1",
diff --git a/scm-plugins/scm-legacy-plugin/package.json b/scm-plugins/scm-legacy-plugin/package.json
index 437e40623e..03c43c145d 100644
--- a/scm-plugins/scm-legacy-plugin/package.json
+++ b/scm-plugins/scm-legacy-plugin/package.json
@@ -13,7 +13,7 @@
"@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT"
},
"devDependencies": {
- "@scm-manager/babel-preset": "^2.11.1",
+ "@scm-manager/babel-preset": "^2.12.0",
"@scm-manager/eslint-config": "^2.11.1",
"@scm-manager/jest-preset": "^2.12.7",
"@scm-manager/plugin-scripts": "^1.0.1",
diff --git a/scm-plugins/scm-svn-plugin/package.json b/scm-plugins/scm-svn-plugin/package.json
index 50bc029b9d..b4b62262f1 100644
--- a/scm-plugins/scm-svn-plugin/package.json
+++ b/scm-plugins/scm-svn-plugin/package.json
@@ -13,7 +13,7 @@
"@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT"
},
"devDependencies": {
- "@scm-manager/babel-preset": "^2.11.1",
+ "@scm-manager/babel-preset": "^2.12.0",
"@scm-manager/eslint-config": "^2.11.1",
"@scm-manager/jest-preset": "^2.12.7",
"@scm-manager/plugin-scripts": "^1.0.1",
diff --git a/scm-ui/ui-api/package.json b/scm-ui/ui-api/package.json
index d4a8af91e7..25f9c17546 100644
--- a/scm-ui/ui-api/package.json
+++ b/scm-ui/ui-api/package.json
@@ -15,7 +15,7 @@
"typecheck": "tsc"
},
"devDependencies": {
- "@scm-manager/babel-preset": "^2.11.2",
+ "@scm-manager/babel-preset": "^2.12.0",
"@scm-manager/eslint-config": "^2.10.1",
"@scm-manager/jest-preset": "^2.12.7",
"@scm-manager/prettier-config": "^2.10.1",
diff --git a/scm-ui/ui-api/src/repositories.ts b/scm-ui/ui-api/src/repositories.ts
index 3f14afe2ad..63506740bf 100644
--- a/scm-ui/ui-api/src/repositories.ts
+++ b/scm-ui/ui-api/src/repositories.ts
@@ -284,7 +284,7 @@ const EXPORT_MEDIA_TYPE = "application/vnd.scmm-repositoryExport+json;v=2";
export const useExportRepository = () => {
const queryClient = useQueryClient();
- const [intervalId, setIntervalId] = useState();
+ const [intervalId, setIntervalId] = useState>();
useEffect(() => {
return () => {
if (intervalId) {
diff --git a/scm-ui/ui-components/package.json b/scm-ui/ui-components/package.json
index 290c7232ff..1b1546a772 100644
--- a/scm-ui/ui-components/package.json
+++ b/scm-ui/ui-components/package.json
@@ -20,7 +20,7 @@
"update-storyshots": "jest --testPathPattern=\"storyshots.test.ts\" --collectCoverage=false -u"
},
"devDependencies": {
- "@scm-manager/babel-preset": "^2.11.2",
+ "@scm-manager/babel-preset": "^2.12.0",
"@scm-manager/eslint-config": "^2.12.0",
"@scm-manager/jest-preset": "^2.12.7",
"@scm-manager/prettier-config": "^2.10.1",
diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap
index b6765931b0..4ff705e8e8 100644
--- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap
+++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap
@@ -2,7 +2,7 @@
exports[`Storyshots Annotate Default 1`] = `