Issues combining KnockoutJS with TypeScript

224 views
Skip to first unread message

Pieter Willemen

unread,
Oct 28, 2022, 6:53:40 AM10/28/22
to KnockoutJS
Hi @mbest and @tomhanax ,

I use Knockout with TS and am currently stuck using TS version 4.5.
Using higher versions of TS (currently trying v4.8.4), I get unexpected errors.
Half of the errors are fixed by the more specific definition suggested by @tomhanax.

```typescript
//export function observable<T>(value: T): Observable<T>;
export function observable<T, U = any>(value?: T extends infer R ? R : U): unknown extends T ? Observable<U> : Observable<T>;
export function observable<T = any>(value: null): Observable<T | null>
```

E.g.: Without the fix, the following results in a TS compiler error:

```typescript
AttestType: Observable<EAttestType> = ko.observable(EAttestType.Consultatie);
```

And, in order to please the TS compiler, would need to be changed to this:
```typescript
AttestType: Observable<EAttestType> = ko.observable<EAttestType>(EAttestType.Consultatie);
```
or this:
```typescript
AttestType: Observable<EAttestType> = ko.observable(EAttestType.Consultatie as EAttestType);
```

However, we still encounter other TS compiler errors, specifically related to types inheriting abstract classes in observables in the following form:

```typescript
export class ModalExistingPatientsComponentParams extends BaseComponentParams {
    ComponentViewModel: Observable<ModalExistingPatientsComponentViewModel | null> = observable<ModalExistingPatientsComponentViewModel | null>(null);

    constructor() {
        super();
    }
}

Property 'ComponentViewModel' in type 'ModalExistingPatientsComponentParams' is not assignable to the same property in base type 'BaseComponentParams'.
  Type 'Observable<ModalExistingPatientsComponentViewModel | null>' is not assignable to type 'Observable<BaseComponentViewModel | null>'.
    Types of parameters 'value' and 'value' are incompatible.
      Type 'BaseComponentViewModel | null' is not assignable to type 'ModalExistingPatientsComponentViewModel | null'.
```

TS says that it cannot assign the base type to the derived type, which is correct.
But the question is, why is it trying to do this in the first place?
I think that the knockout TS definitions are not supporting working with derived types in observables.

Here is a simplified playground detailing the issue:
[Playground link](https://www.typescriptlang.org/play?ts=4.8.4#code/JYOwLgpgTgZghgYwgAgPICMDO0Bud0A2EAPACoB8yA3gFDLIAUAlAFzKkDcdjeBArhDalWyOCACeXAL40aAejnIAJhAQE4UFDD4gEYYAHsQyA1lz4iZcg14ChIjNih5CJClxVqNWnXsPHTJxdLUmQAXlEJa1tBZBA+AgIHM2cLN2QAHziEgnIaT3VNZG1dfSMTFOC3ABpkAFVwyPFouH4IAH4hZAgAD0gQJUxkUBhoZAAlZHaJ5DY6kR0AaxADAHdjXv7B9im0SrTiOso2R3NXKy5ZXoAHAygwUSwwKEQHr0whgCE4bABhAwAtrcQBBwAA1YAQVYAWQMKgI1G49AAkpgADIGOBKUAAcxO+3O6AMBiIYkoEUCZyIDGeAiYXHoKMw-xAmFpeggSnxQQORJJEDJjUpqVcDHgBGw9NkjOQCCMbKgfD0dwY1w0cABmDY3z+gOBoLAAAV1ZqmIiZTK1S9NQA6f5AowGiFQ2HwmkAC2AmClMpkSOQiwMABEIJgkAMxGBmXqiJBGsxwpRaBbGWBPZgbaiWQqlZAlDTFRAfYyZH6bncHvgFa9ZeoPsgdRB7frwABlVRlEDOmFwiAI5OM1EYrG47lUkh80kgckVHmi2lFhmD6Os9l5sciyyTgXToUE6niyWXGVy1eK5VQVUmrUNn5NvWOtsd-zG63e80p5BWjUZ5uPsDtn4Rjdq6fYel6xb0H6MqBiGYagkokbRkCsYoBECZhEm-oymmXqZiuOYcvmC6QcgpZXD0tz3I81Z6LWPxfHef4guAr4-h+9BVs8NbMU6kI9vCG5VMQja8eC-GgQiWTxIk5DSBRVGVk8Lx0e8jG6g6LEAc+RhsZqHE0dxdFidpQFdhJvYEEJByiQ+WmAZ2IGWZk2SyUunHKTWr4GiZTmCbeGktmAfl9vJNDltRanICZLKQH0BnfpqACE2pMXZBp6UMWS2ZpBoOS+17Hoyp6EWAKrYYyiU3jlQWZS5NX-vlunXv6ZoDimuEZlVjRVe5ZE0GWlEVvR9auq0ACiPRevoIA4sa+gGshtXXt0fQIep965axK3tdF6XiS6lnWecY0EJN024vNkLgEt-4hVJrm5Huc6WKd51spdcALTdvkWfCLkybkDCA1K-olWuKptRV9CYHw1zQMwfXkeFQ2RXWQxvVNH2zVdi2-Yd-2bOtAWbUF90GUYrZwDgEC4+AvytAQ6CIIsKWMBhlA4AYwBKGa0k5H1ACCYCQGypDiPDx2WONwui2A4vwzOwpVAwMsi6G8sSxANqCwM0CLtKxXyhDl5VWwmMXTjX3XVGJmZVDn7ILD8Om9epHIxFDygnwALIGrcsKygu26yomjVP6qCzaGCCeosaYQDz4cymC0DXEQEA4osOjYjiEBJ4y2YJGA1sQANshAA)

I posted this also on github.
https://github.com/knockout/knockout/issues/2589

Julio Di Egidio

unread,
Dec 11, 2022, 7:22:28 AM12/11/22
to KnockoutJS
On Friday, 28 October 2022 at 12:53:40 UTC+2 pieterw...@gmail.com wrote:

> TS says that it cannot assign the base type to the derived type, which is correct.
> But the question is, why is it trying to do this in the first place?

There are so many problems with that code.  But even before the TypeScript,
I cannot get my head around why you would initialize/read/write an observer
with a "view model component"...?

Julio

Julio Di Egidio

unread,
Dec 11, 2022, 7:28:01 AM12/11/22
to KnockoutJS
An observable...
Reply all
Reply to author
Forward
0 new messages