What does type <U extends SimpleArgs, R> extends BasicAsyncFunc<U, R> mean? [duplicate] - javascript

I have these below type defined,
import { ReadonlyDeep } from 'type-fest';
// We don't allow null. undefined is required instead.
export type SimpleArgs = (string | number | boolean | undefined)[];
export type BasicAsyncFunc<U extends SimpleArgs, R> = (...args: U) => Promise<ReadonlyDeep<R>>;
interface Memoized<U extends SimpleArgs, R> extends BasicAsyncFunc<U, R> {
cache_size: () => number;
clear_cache: () => void;
}
I get the SimpleArgs type. It can be an array of primitive values.
What is the signature of BasicAsyncFun and Memoized?
What does
interface Memoized<U extends SimpleArgs, R> extends BasicAsyncFunc<U, R> {
cache_size: () => number;
clear_cache: () => void;
}
mean?
In below defined memoized_async()
options: { ttl: number; size: number },
f: BasicAsyncFunc<U, R>,
): Memoized<U, R> => {
return Object.assign(f, {
cache_size: () => {
return Object.keys(cacheStorage).length;
},
clear_cache: () => {
cacheStorage = {};
},
});
};
What type of arguments does f expects? What's the return type?

Related

HMS Core location Kit TypeError: Cannot read properties of undefined (reading 'getFusedLocationProviderClient') - Ionic/Capacitor - VueJS

I'm trying to implement HMS Core location kit into my vue ionic app.
I import HMSLocation and declare it, but when I try to use the getFusedLocationProviderClient function I get
TypeError: Cannot read properties of undefined (reading 'getFusedLocationProviderClient')
import { HMSLocation } from "#hmscore/ionic-native-hms-location/ngx";
export default {
data() {
return {
hmsLocation: null,
fusedClient: null,
locationResult: null,
};
},
mounted() {
this.getLocation();
},
methods: {
async getLocation() {
this.hmsLocation = new HMSLocation();
console.log(this.hmsLocation);
this.fusedClient = this.hmsLocation.getFusedLocationProviderClient();
this.locationResult = await this.fusedClient.getLastLocation;
},
},
.....
console.log(this.hmsLocation); returns
node_modules/#hmscore/ionic-native-hms-location/ngx
import { IonicNativePlugin } from '#ionic-native/core';
export declare class HMSLocation extends IonicNativePlugin {
getGeofenceService(): GeofenceService;
getGeocoderService(language: string, country?: string): GeocoderService;
getFusedLocationProviderClient(): FusedLocationService;
getActivityIdentificationService(): ActivityIdentificationService;
addListener(event: Events, callback: (data: LocationResult | [] | ActivityConversionResponse | ActivityIdentificationResponse) => void): any;
disableLogger(): Promise<void>;
enableLogger(): Promise<void>;
}
export declare class BackgroundManager {
private constructor();
static notify(notificationId: number, notification: string): void;
static makeToast(text: string, duration: number): void;
}
export interface FusedLocationService {
disableBackgroundLocation(): Promise<void>;
enableBackgroundLocation(notificationId: number, notification: string): Promise<void>;
checkLocationSettings(request: LocationSettingsRequest): Promise<LocationSettingsStates>;
flushLocations(): Promise<void>;
getLastLocation(): Promise<Location>;
getLastLocationWithAddress(request: LocationRequest): Promise<HWLocation>;
getLocationAvailability(): Promise<boolean>;
getNavigationContextState(requestType: NavigationRequestConstants): Promise<NavigationResult>;
removeLocationUpdates(requestCode: number, type: RequestType): Promise<boolean>;
requestLocationUpdates(requestCode: number, request: LocationRequest, callback?: (locationResult: LocationResult) => void): Promise<boolean>;
requestLocationUpdatesEx(requestCode: number, request: LocationRequest): Promise<boolean>;
setMockLocation(latLng: LatLng): Promise<void>;
setMockMode(mode: boolean): Promise<void>;
setLogConfig(logConfigSettings: LogConfigSettings): Promise<void>;
getLogConfig(): Promise<LogConfigSettings>;
}

Vue 3 TypeScript - Property 'searchData' does not exist on type 'CreateComponentPublicInstance

im trying to use function as a computed value in defineComponent:
code printscreen
<script lang="ts">
import { defineComponent } from "#vue/runtime-core";
import { testData } from "../assets/testData";
export type SearchDataType = {
_id: string;
index: number;
name: string;
};
interface ISearchPage {
searchData: SearchDataType[];
searchQuery: string
}
export default defineComponent({
name: "SearchPage",
components: {},
data(): ISearchPage {
return {
searchData: [],
searchQuery: ''
};
},
methods: {
getData: function () {
this.searchData = testData;
},
},
created(){
this.getData()
},
computed: {
filteredSearch: function() {
return this.searchData.filter((filteredItem: SearchDataType) => {
return filteredItem.name.match(this.searchQuery)
})
}
}
});
</script>
And, when i want to use this.searchData variable in computed im reciving the following errors:
Property 'searchData' does not exist on type 'CreateComponentPublicInstance<{ [x: string & `on${string}`]: ((...args: any[]) => any) | undefined; } | { [x: string & `on${string}`]: undefined; }, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 10 more ..., {}>'.
Property 'searchData' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $props: { [x: string & `on${string}`]: ((...args: any[]) => any) | undefined; } | { [x: string & `on${string}`]: undefined; }; ... 10 more ...; $watch(source: string | Function, cb: Function, options?: WatchOptions<...> | undefined): WatchStopHandle; } & ... 4 more ... & Co...'
I was trying to add the code below to shims-vue.d.ts file, but it didn't solve the problem:
import { ComponentCustomProperties } from "vue";
declare module "#vue/runtime-core" {
interface CreateComponentPublicInstance {
searchData: any | null;
}
}
Im new to vue with TypeScript. Could someone tell me, what am doing wrong?

Typescript: es6 import type definition (.d.ts) from node_modules subfolder

I have a npm package that has the following type definitions (simplified):
./node_modules/ag-grid-react/main.d.ts
export declare class AgGridReact extends Component<AgGridReactProps, {}> {}
./node_modules/ag-grid-react/lib/agGridReact.d.ts
export declare class AgGridReact extends Component<AgGridReactProps, {}> {
gridOptions: GridOptions;
api: GridApi | null;
columnApi: ColumnApi;
}
I am using the component in my react component like this:
import { AgGridReact } from 'ag-grid-react'
const HelpRequests= () => {
const grid = useRef<AgGridReact>(null)
if (grid.current) console.log(grid.current.columnApi)
return (<AgGridReact ref={grid}/>)
}
The Problem:
Typescript does complain that there is no columnApi. It seems it sadly picks the wrong type from the main.d.ts
I found that I can import the type from the agGridReact.d.ts directly and use it like this:
import {AgGridReact as AgGridReactType} from 'ag-grid-react/lib/agGridReact'
...
const grid = useRef<AgGridReactType>(null)
Question:
Is this the correct way to address this issue? Will typescript be smart enough not to import the ./node_modules/ag-grid-react/lib/agGridReact.ts file which could cause my bundle size to go up?
I've searched a lot but could not find anything about importing types only from node_modules subfolders.
I will try to answer this:
Let's assume there is an xyz library and it has these files:
xyz/lib/main.ts:
export const test = 1000
and
xyz/main.ts:
export * from './lib/main.ts'
export const test = 'foo bar'
And I would like to use xyz in my app.ts, and I am aware of only its main.ts file as I think it is the main file which exports everything from library. So I am most likely to do:
app.ts:
import { test } from './xyz/main'
console.debug(test) // it will print 'foo bar'
Now, somebody goes and comment this line in the library:
xyz/main.ts:
export * from './lib/main.ts'
// export const test = 'foo bar'
Now, what will be printed by my app.ts? It will print 1000.
The same thing is happening there with ag-grid-react. It (ag-grid-react/main.d.ts) is overriding the apparently correct (better) class declaration present in ag-grid-react/lib/agGridReact.d.ts. And it is perfectly fine to import from inner path.
main.d.ts:
export * from './lib/agGridReact'; // it is exporting from innner path too
export declare class AgGridColumn extends Component<AgGridColumnProps | AgGridColumnGroupProps, {}> { // and overriding here at the same time
}
agGridReact.d.ts:
export declare class AgGridReact extends Component<AgGridReactProps, {}> {
props: any;
state: any;
static propTypes: any;
gridOptions: GridOptions;
changeDetectionService: ChangeDetectionService;
api: GridApi | null;
columnApi: ColumnApi;
portals: ReactPortal[];
hasPendingPortalUpdate: boolean;
destroyed: boolean;
protected eGridDiv: HTMLElement;
private static MAX_COMPONENT_CREATION_TIME;
constructor(props: any, state: any);
render(): React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)>) | (new (props: any) => React.Component<any, any, any>)>;
createStyleForDiv(): any;
componentDidMount(): void;
waitForInstance(reactComponent: ReactComponent, resolve: (value: any) => void, runningTime?: number): void;
mountReactPortal(portal: ReactPortal, reactComponent: ReactComponent, resolve: (value: any) => void): void;
batchUpdate(callback?: any): any;
destroyPortal(portal: ReactPortal): void;
private getStrategyTypeForProp;
shouldComponentUpdate(nextProps: any): boolean;
componentDidUpdate(prevProps: any): void;
processPropsChanges(prevProps: any, nextProps: any): void;
private extractDeclarativeColDefChanges;
private extractGridPropertyChanges;
componentWillUnmount(): void;
isDisableStaticMarkup(): boolean;
}
I can't exactly say why ag-grid did this. I found this looking at the typing files. I may be incorrect too.

Extending Interface/types in typescript

I have extended my FilterMetaData type to add a dynamic model which is different structure for different entities but somehow typescript not recognizing my object properties. I might be missing something here.
Interfaces
export type FilterMetaData<T extends {}> = T & {
filterCriteriaID: number;
filterCriteriaName?: string;
isDefaultSelected?: boolean;
isExpanded?: boolean;
}
export interface DateRange {
data?: DateRangeData;
}
export interface DateRangeData {
min?: Date;
max?: Date;
}
export interface Range {
data?: RangeData;
}
export interface RangeData {
currency?: string;
timePeriod?: string;
min?: number;
max?: number;
step?: number;
}
export interface Select {
data?: SelectData[];
}
export interface SelectData {
id?: number;
name?: string;
isSelected?:boolean|false;
parentID?: number | null;
parentName?: string;
}
Implementation in class
helper<T1 extends FilterMetaData<T2>>(filter) {
this.selectedFilterService.getAppliedFilterMasterData<T1>(filter)
.pipe(takeUntil(this.unsubscribe$))
.subscribe((filterData: T1) => {
if (filter.isDefaultSelected) {
filterData.isExpanded = false;
filterData.data.forEach((data) => data.isSelected = false);
this.selectedFilters.result.select.push(filterData);
this.loadComponent(new FilterComponentType(SelectComponent, filterData));
} else {
this.removeComponent(filter);
}
}, err => {
this.toastrService.error(err);
})
}
Invoking Function with type args like this:--
this.helper<FilterMetaData<Select>>(filter);

MediaStreamRecorder is not a constructor

I'm new to Angular6 and I'm trying to use MediaStreamRecorder. I'm definitely doing something wrong when defining MediaStreamRecorder because I keep getting the error TypeError: msr__WEBPACK_IMPORTED_MODULE_4__.MediaStreamRecorder is not a constructor. Not sure how or where should I declare and define MediaStreamRecorder. Can you help me with this, please?
I have installed msr module, and my code looks like this:
import { Component,ViewChild, OnInit, Inject } from '#angular/core';
import { LinksService } from 'demo/_services/links.service';
import { Http,Response,Headers } from '#angular/http';
import { MediaStreamRecorder} from 'msr';
import { RecordRTC } from 'recordrtc';
#Component({
selector: 'demo-ceva',
templateUrl: './ceva.component.html',
styleUrls: ['./ceva.component.css'],
providers: [
{
provide: SpeechRecognitionLang,
useValue: 'en-US',
},
SpeechRecognitionService,
],
})
export class CevaComponent {
public navigator: any;
public MediaStreamRecorder: any;
constructor( private http: Http, private service: SpeechRecognitionService, private links: LinksService ) {
this.record = () => {
var browser = <any>navigator;
var obj = { audio: true, video:false };
browser.getUserMedia = (browser.getUserMedia || browser.webkitGetUserMedia || browser.mozGetUserMedia || browser.msGetUserMedia);
browser.mediaDevices.getUserMedia(obj).then(stream => {
var source = window.URL.createObjectURL(stream);
var config= { ... }
var recorder = new MediaStreamRecorder(stream, config);
recorder.record();
recorder.stop(function(blob) {
var blob = recorder.blob;
console.log(blob);
});
});
});
As the answer to this post suggested, the solution to me was that in typings.d.ts file to add the following declarations:
declare interface MediaRecorderErrorEvent extends Event {
name: string;
}
declare interface MediaRecorderDataAvailableEvent extends Event {
data : any;
}
interface MediaRecorderEventMap {
'dataavailable': MediaRecorderDataAvailableEvent;
'error': MediaRecorderErrorEvent ;
'pause': Event;
'resume': Event;
'start': Event;
'stop': Event;
'warning': MediaRecorderErrorEvent ;
}
declare class MediaRecorder extends EventTarget {
readonly mimeType: string;
// readonly MimeType: 'audio/wav';
readonly state: 'inactive' | 'recording' | 'paused';
readonly stream: MediaStream;
ignoreMutedMedia: boolean;
videoBitsPerSecond: number;
audioBitsPerSecond: number;
ondataavailable: (event : MediaRecorderDataAvailableEvent) => void;
onerror: (event: MediaRecorderErrorEvent) => void;
onpause: () => void;
onresume: () => void;
onstart: () => void;
onstop: () => void;
constructor(stream: MediaStream);
start();
stop();
resume();
pause();
isTypeSupported(type: string): boolean;
requestData();
addEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaStream, ev: MediaRecorderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaStream, ev: MediaRecorderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
And in my component, I was able to use var mediaRecorder = new MediaRecorder(stream); without any other declarations. Thank you, #firegloves , for the link to this post and thank you, #Tiberiu C. for the answer! It was really helpful.
npm install -D #types/dom-mediacapture-record
I had the same issue with pure JS and React and removing the following line "fixed" the problem:
window.MediaRecorder = require('audio-recorder-polyfill');

Categories

Resources