Export function as "root" of module? - javascript

When writing a TypeScript definition, how do you declare that the definition defines a function, rather than a type? So that the function is exported as the module itself...
Definition
declare module "rmdir" {
interface IRmDirCallback {
(err: any, dirs: Array<string>, files: Array<string>): any;
}
function rmdir(dir: string, options: any, callback: IRmDirCallback): void;
export = rmdir;
}
export = rmdir.rmdir;
Usage Example
/// <reference path="rmdir.d.ts"/>
import rmdir = require("rmdir");
rmdir("test", { }, (err: any, dirs: Array<string>, files: Array<string>) => { });
So when I import rmdir, I dont' want to have to call rmdir.rmdir(...).

Use export =. Here is the complete code:
declare module "rmdir" {
function rmdir(dir: string, options: any, callback: (err: any, dirs: Array<string>, files: Array<string>) => any): void;
export = rmdir;
}

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>;
}

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.

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');

Issue related to import/export with typings

I have JS file and want to write typings for it.
import { ApiService } from './src/ApiService'
Then I write typings and export it
export declare class ApiService {
constructor(adapter: any, options: any);
on:(evt, cb) => any;
extend: (opts) => any;
}
error TS2440: Import declaration conflicts with local declaration of ApiService
How can I fix It?
Put your declaration in a file ApiService.d.ts (but the keyword declare is unnecessary):
// src/ApiService.d.ts
export class ApiService {
constructor(adapter: any, options: any);
on:(evt, cb) => any;
extend: (opts) => any;
}
Notice that the TS definition file name must be the same as the JavaScript file name: ApiService.d.ts describes a JavaScript file ApiService.js.
Then, import it:
// test.ts
import { ApiService } from './src/ApiService'
It should works.

Typescript definition file for javascript class throws runtime error

I am using Visual Studio 2015 IDE.
I have a file Messaging.d.ts. It defines a couple of classes written in javascript. The definition in the TS file is written as follows:
declare module 'Messaging' {
export default class DisplayMessageManager {
AddMainMessage(message: string, alertCssClass: string): void;
DontShowTipAgain(alertID: string): void;
CloseTip(alertID: string, showAlertTime: number): void;
TogglePanelDirty(panelID: string, isDirty: boolean, originalState: string): void;
}
}
declare module 'MessagingConstants' {
export default class Constants {
//Bootstrap Alert Classes
bsSuccess: string;
bsWarning: string;
bsDanger: string;
bsInfo: string;
bsDefault: string;
bsPrimary: string;
}
}
When I import this in my app.ts file (in the same folder) I use:
import DisplayMessageManager from 'Messaging';
import Constants from 'MessagingConstants';
and then:
messageManager: DisplayMessageManager = new DisplayMessageManager();
messageConstants: Constants = new Constants();
later I use:
this.messageManager.AddMainMessage('test', this.messageConstants.bsSuccess);
This all compiles correctly. However, when I run the code the error in the console tells me that it cannot find the file 'Messaging.js'. I did not think that a typescript definition file needed to compile into a javascript file. What am I doing wrong to get these external javascript classes to work?
Since you're using non-relative paths (i.e. "Messaging" instead of "./Messaging"), if you're using CommonJS, this means you should have a node_modules/Messaging/ and node_modules/MessagingConstants/.
I'm not sure if that's actually what you want. What you may've meant to do is create the following two declaration files to reflect the exact shape of your local .js files
Messaging.d.ts:
export default class DisplayMessageManager {
AddMainMessage(message: string, alertCssClass: string): void;
DontShowTipAgain(alertID: string): void;
CloseTip(alertID: string, showAlertTime: number): void;
TogglePanelDirty(panelID: string, isDirty: boolean, originalState: string): void;
}
MessagingConstants.d.ts:
export default class Constants {
//Bootstrap Alert Classes
bsSuccess: string;
bsWarning: string;
bsDanger: string;
bsInfo: string;
bsDefault: string;
bsPrimary: string;
}
And then include them like so:
import DisplayMessageManager from './Messaging';
import Constants from './MessagingConstants';

Categories

Resources