Skip to content

Commit 6eee6bf

Browse files
committed
test
1 parent e2c797f commit 6eee6bf

File tree

3 files changed

+54
-17
lines changed

3 files changed

+54
-17
lines changed

packages/angular-table/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
],
4444
"scripts": {
4545
"clean": "rimraf ./build",
46-
"test:types": "tsc --noEmit",
46+
"test:types": "tsc --noEmit && vitest --typecheck",
4747
"test:lib": "vitest",
4848
"test:lib:dev": "vitest --watch",
4949
"build": "ng-packagr -p ng-package.json -c tsconfig.build.json && rimraf ./build/lib/package.json"

packages/angular-table/src/flex-render/flex-render-component.ts

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
ComponentMirror,
33
Injector,
4+
input,
45
InputSignal,
56
reflectComponentType,
67
Type,
@@ -9,27 +10,36 @@ import {
910
type Inputs<T> = {
1011
[K in keyof T as T[K] extends InputSignal<infer R>
1112
? K
12-
: never]: T[K] extends InputSignal<infer R> ? R : never
13+
: never]?: T[K] extends InputSignal<infer R> ? R : never
1314
}
1415

15-
type HasUndefinedProperty<T> = keyof T extends never
16-
? true
17-
: keyof {
18-
[K in keyof T as undefined extends T[K] ? K : never]: T[K]
19-
} extends never
20-
? false
21-
: true
16+
type OptionalKeys<T, K = keyof T> = K extends keyof T
17+
? T[K] extends Required<T>[K]
18+
? undefined extends T[K]
19+
? K
20+
: never
21+
: K
22+
: never
2223

23-
interface FlexRenderRequiredOptions<
24-
TComponent,
25-
TInputs extends Record<string, any>,
26-
> {
24+
interface FlexRenderRequiredOptions<TInputs extends Record<string, any>> {
25+
/**
26+
* Component instance inputs. They will be set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)
27+
*/
2728
inputs: TInputs
29+
/**
30+
* Optional {@link Injector} that will be used when rendering the component
31+
*/
2832
injector?: Injector
2933
}
3034

31-
interface FlexRenderOptions<TComponent, TInputs extends Record<string, any>> {
35+
interface FlexRenderOptions<TInputs extends Record<string, any>> {
36+
/**
37+
* Component instance inputs. They will be set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)
38+
*/
3239
inputs?: TInputs
40+
/**
41+
* Optional {@link Injector} that will be used when rendering the component
42+
*/
3343
injector?: Injector
3444
}
3545

@@ -44,9 +54,9 @@ export function flexRenderComponent<
4454
TInputs extends Inputs<TComponent> = Inputs<TComponent>,
4555
>(
4656
component: Type<TComponent>,
47-
...options: HasUndefinedProperty<TInputs> extends true
48-
? [FlexRenderOptions<TComponent, TInputs>?]
49-
: [FlexRenderRequiredOptions<TComponent, TInputs>]
57+
...options: OptionalKeys<TInputs> extends never
58+
? [FlexRenderOptions<TInputs>?]
59+
: [FlexRenderRequiredOptions<TInputs>]
5060
) {
5161
const { inputs, injector } = options?.[0] ?? {}
5262
return new FlexRenderComponent(component, inputs, injector)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { input } from '@angular/core'
2+
import { test } from 'vitest'
3+
import { flexRenderComponent } from '../src'
4+
5+
test('Infer component inputs', () => {
6+
class Test {
7+
readonly input1 = input<string>()
8+
}
9+
10+
// @ts-expect-error Must pass right type as a value
11+
flexRenderComponent(Test, { inputs: { input1: 1 } })
12+
13+
// Input is optional so we can skip passing the property
14+
flexRenderComponent(Test, { inputs: {} })
15+
})
16+
17+
test('Options are mandatory when given component has required inputs', () => {
18+
class Test {
19+
readonly input1 = input<string>()
20+
readonly requiredInput1 = input.required<string>()
21+
}
22+
23+
// @ts-expect-error Required input
24+
flexRenderComponent(Test)
25+
26+
flexRenderComponent(Test, { inputs: { requiredInput1: 'My value' } })
27+
})

0 commit comments

Comments
 (0)