feat(typings): Enhance typing support with withAppTypes and custom services throughout OHIF (#4090)
This commit is contained in:
1 parent
b2cd0172d6
commit
374065bc3b
153 files changed
+842
-657
No files matched your search
@@ -0,0 +1,85 @@
|
||||
---
|
||||
sidebar_position: 10
|
||||
sidebar_label: Global Types
|
||||
---
|
||||
|
||||
# Extending App Types and Services in Your Application
|
||||
|
||||
This documentation provides an overview and examples on how to use and extend `withAppTypes`, integrate custom properties, and add services in the global namespace of the application. This helps in enhancing the application's modularity and extensibility.
|
||||
|
||||
## Overview of `withAppTypes`
|
||||
|
||||
The `withAppTypes` function is a TypeScript utility that extends the base properties of components or modules with the application's core service and manager types. It allows for a more flexible and type-safe way to pass around core functionality and custom properties.
|
||||
|
||||
### Using `withAppTypes`
|
||||
|
||||
`withAppTypes` can be enhanced using generics to include custom properties. This is particularly useful for passing additional data or configurations specific to your component or service.
|
||||
|
||||
### Extending with Custom Properties
|
||||
|
||||
You can extend `withAppTypes` to include custom properties by defining an interface for the props you need. For example:
|
||||
|
||||
```typescript
|
||||
interface ColorbarProps {
|
||||
viewportId: string;
|
||||
displaySets: Array<any>;
|
||||
colorbarProperties: ColorbarProperties;
|
||||
}
|
||||
|
||||
export function Colorbar({
|
||||
viewportId,
|
||||
displaySets,
|
||||
commandsManager, // injected type
|
||||
servicesManager, // injected type
|
||||
colorbarProperties,
|
||||
}: withAppTypes<ColorbarProps>): ReactElement {
|
||||
// Component logic here
|
||||
}
|
||||
```
|
||||
|
||||
In this example, `ColorbarProps` is a custom interface that extends the application types through `withAppTypes`.
|
||||
|
||||
## Typing the custom extensions's new services
|
||||
|
||||
Extensions can define additional services that integrate seamlessly into the application's global service architecture, and will be available on the ServicesManager for use across the application.
|
||||
|
||||
### Adding the extension's services Types
|
||||
|
||||
Declare your service in the global namespace and use it across your application as demonstrated below:
|
||||
|
||||
`extensions/my-extension/src/types/whatever.ts`
|
||||
|
||||
```typescript
|
||||
declare global {
|
||||
namespace AppTypes {
|
||||
// only add if you need direct access to the service ex. AppTypes.MicroscopyService
|
||||
export type MicroscopyService = MicroscopyServiceType;
|
||||
// add to the global Services interface, and to withAppTypes
|
||||
export interface Services {
|
||||
microscopyService?: MicroscopyServiceType;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Doing the above adds the `microscopyService` to the global Services interface, which ServicesManager uses by default `public services: AppTypes.Services = {};` to type services, and is also used by withAppTypes to inject services into components.
|
||||
You will also get access to the seperate services via `AppTypes.YourServiceName` in your application.
|
||||
|
||||
|
||||
```typescript
|
||||
export function CustomComponent({
|
||||
servicesManager,
|
||||
}: withAppTypes<CustomComponentProps>): ReactElement {
|
||||
const { microscopyService } = servicesManager.services;
|
||||
microscopyService.someMethod(); // auto completation available
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
export function CustomComponent2(
|
||||
microscopyService: AppTypes.MicroscopyService,
|
||||
): ReactElement {
|
||||
microscopyService.someMethod(); // auto completation available
|
||||
}
|
||||
```
|
||||
@@ -36,11 +36,11 @@ for `OHIF-v3`.
|
||||
// new service inside new extension
|
||||
import MyNewService from './MyNewService';
|
||||
|
||||
export default function MyNewServiceWithServices(serviceManager) {
|
||||
export default function MyNewServiceWithServices(servicesManager) {
|
||||
return {
|
||||
name: 'MyNewService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new MyNewService(serviceManager);
|
||||
return new MyNewService(servicesManager);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -146,12 +146,12 @@ and the logic for your service shall be
|
||||
// Canonical name of upper camel case BackEndService for the class
|
||||
import BackEndService from './BackEndService';
|
||||
|
||||
export default function WrappedBackEndService(serviceManager) {
|
||||
export default function WrappedBackEndService(servicesManager) {
|
||||
return {
|
||||
// Note the canonical name of lower camel case backEndService
|
||||
name: 'backEndService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new BackEndService(serviceManager);
|
||||
return new BackEndService(servicesManager);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -161,8 +161,8 @@ with implementation of
|
||||
|
||||
```ts
|
||||
export default class BackEndService {
|
||||
constructor(serviceManager) {
|
||||
this.serviceManager = serviceManager;
|
||||
constructor(servicesManager) {
|
||||
this.servicesManager = servicesManager;
|
||||
}
|
||||
|
||||
putAnnotations() {
|
||||
|
||||
@@ -28,7 +28,7 @@ We maintain the following non-ui Services:
|
||||

|
||||
|
||||
> We have explained services and how to create a custom service in the
|
||||
> [`ServiceManager`](../../managers/service.md) section of the docs
|
||||
> [`ServicesManager`](../../managers/service.md) section of the docs
|
||||
|
||||
To recap: The simplest service return a new object that has a `name` property,
|
||||
and `Create` method which instantiate the service class. The "Factory Function"
|
||||
@@ -39,11 +39,11 @@ different for UI Services).
|
||||
// extensions/customExtension/src/services/backEndService/index.js
|
||||
import backEndService from './backEndService';
|
||||
|
||||
export default function WrappedBackEndService(serviceManager) {
|
||||
export default function WrappedBackEndService(servicesManager) {
|
||||
return {
|
||||
name: 'myService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new backEndService(serviceManager);
|
||||
return new backEndService(servicesManager);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user