Class Interface Function Definition - TypeError: Object does not support property or method

I wrote a construction similar to the one below in an Angular application (this was greatly simplified to demonstrate this problem). What would prevent a function from filterProperty()defining in an instance iteminside a class DemoSource?

export a keyword is used because each construct is defined in a separate file.

export interface IProperty {
    filterProperty(): string;
}

export class Demo implements IProperty {
    displayName: string;

    filterProperty(): string {
        return this.displayName;
    }
}

export class DemoSource<TItem extends IProperty> {
    filterChange = new BehaviorSubject('');
    filteredData: TItem[];

    constructor(private service: IService<TItem>) {
        // A BehaviorSubject<Array<TItem>> from a service
        this.filteredData = service.data.value.slice();
    }

    connect(): Observable<TItem[]> {
        return Observable.merge(this.service.data).map(() => {
            this.filteredData = this.service.data.value.slice().filter((item: TItem) => {
                // Object doesn't support property or method 'filterProperty'
                const searchStr = item.filterProperty().toLowerCase();
                return searchStr.indexOf(this.filter.toLowerCase()) !== -1;
            });

            return filteredData;
        });
    }
}

When debugging at the point where it is called item.filter(), I get the following error:

ERROR TypeError: Object doesn't support property or method 'filterProperty'

Update
Changed the contract function IPropertyfrom filter()to filterProperty()to avoid confusion.

Here is the error:

error

, item , , filterProperty(), ( proto):

item


:

@Injectable()
export class IdentityService implements IService<AppUser> {
    users = new BehaviorSubject<Array<AppUser>>([]);
    public get data(): BehaviorSubject<AppUser[]> { return this.users; }
}

export interface IService<T> {
    data: BehaviorSubject<T>;
}

, API:
service

API :
api

-

- JavaScript

Object.defineProperty(exports, "__esModule", { value: true });
var Demo = (function () {
    function Demo() {}
    Object.defineProperty(Demo.prototype, "filter", {
        get: function () { return this.displayName; },
        enumerable: true,
        configurable: true
    });
    return Demo;
}());
exports Demo = Demo;


- : Typescript/ API API
GitHub Repo -: typescript-interface-issues

+1
3

JSON , , , Object Array.

item filterProperty, . DemoSource<IProperty>, , IProperty filterProperty. TypeScript , , - , .

, , ( ). , , :

export interface IItemData {
    displayName: string;
    id?: number;
    ...
}

export class Item implements IItemData {
    displayName: string;

    constructor({ displayName }: IItemData) {
        this.displayName = displayName;
    }

    filterProperty(): string {
        return this.displayName;
    }
}

, item:

export class DemoSource<TItem extends IItemData> {
    ...
    this.filteredData = this.service.data.value.slice()
    .map((item: TItem) => {
        // item doesn't have 'filterProperty'
        return new Item(item); 
    })
    .filter((item: Item) => {
        // item has 'filterProperty'
        const searchStr = item.filterProperty().toLowerCase();
        return searchStr.indexOf(this.filter.toLowerCase()) !== -1;
    });
    ...
+3

, filter . angular filter Object. filter Array. .

. , Object TTem. .

this.filteredData = this.service.data.value.slice().filter(
(item: TItem) => {
            // Object doesn't support property or method 'filter'
            let instance: TItem = new TItem();
            Object.assign(instance, item);
            const searchStr = instance.filter().toLowerCase();
            return searchStr.indexOf(this.filter.toLowerCase()) !==-1;
        });
0

I managed to get it to work the way I originally wanted it to be with the setting below. The key apparently added a property filterto the C # object, which was used to serialize data in JSON through the Web API. Not sure why this is required, since TypeScript should be able to extend the model obtained from the Web API with additional features.

The example is simplified to demonstrate a set of problems.

DemoModel.cs

// C# Class JSON is serialized from via Web API
public class DemoModel
{
    public string displayName { get; set; }
    public string filter
    {
        get { return displayName; }
    }
}

iproperty.interface.ts

export interface IProperty {
    filter: string;
}

demo.model.ts

import { IProperty } from '../interfaces/iproperty.interface';

export class Demo implements IProperty {
    displayName: string;
    get filter(): string { return this.displayName; }
}

core.datasource.ts

export class CoreDataSource<TItem extends IProperty> {
    filterChange = new BehaviorSubject('');
    filteredData: TItem[];
    get filter(): string { return this.filterChange.value; }
    set filter(filter: string) { this.filterChange.next(filter); }

    constructor(private service: IService<TItem>) {
        super();
        this.filteredData = service.data.value.slice();
    }

    connect(): Observable<TItem[]> {
        const displayDataChanges = [
            this.service.data,
            this.filterChange
        ];

        return Observable.merge(...displayDataChanges).map(() => {
            this.filteredData = this.service.data.value.slice().filter((item: TItem) => {
                const searchStr = item.filter.toLowerCase();
                return searchStr.indexOf(this.filter.toLowerCase()) !== -1;
            });

            return filteredData;
        });
    }
}
0
source

Source: https://habr.com/ru/post/1687915/


All Articles