Typescript definition file for javascript class throws runtime error - javascript

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

Related

JavaScript - How to show interface suggestions for every typing

Hello I'm newbie at JavaScript and I wan to create a interface but the interface's variable's name is not gonna be a fix name. So the Interface have to return the suggestions for every name that I write.
Inside of my Interface file:
export interface ArchiveData {
id: string;
latest_reel_media: number;
seen?: any;
...
}
export interface Reels {
anyArchiveName: ArchiveData;
}
export interface ArchivedStoryDataResponse {
reels: Reels;
status: string;
}
The result with fixed name:
The result with another name; no suggestions:
Well, it's been a long time but I finally reached my goal 😅
export interface ArchiveData {
id: string;
latest_reel_media: number;
seen?: any;
...
}
export interface Reels {
[reel_id:string]: ArchiveData;// this line
}
export interface ArchivedStoryDataResponse {
reels: Reels;
status: string;
}

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.

Typescript import a React js component which d.ts file writed by myself and occured Module not found: Can't resolve 'xxx' in 'xxx'

I added a component js's d.ts file as below:
/// <reference types="react" />
declare namespace __ReactAvatarEditor {
interface croppingRect {
x: number,
y: number,
width: number,
height: number
}
interface point {
x: number,
y: number
}
export interface AvatarEditorProps {
scale?: number,
rotate?: number,
image?: any,
border?: number | [number],
borderRadius?: number,
width?: number,
height?: number,
position?: point,
color?: number[],
style?: object,
crossOrigin?: string,
onDropFile?: any,
onLoadFailure?: any,
onLoadSuccess?: any,
onImageReady?: any,
onImageChange?: any,
onMouseUp?: any,
onMouseMove?: any,
onPositionChange?: any,
disableDrop?: boolean
}
export class AvatarEditor extends React.Component<AvatarEditorProps> {
}
}
declare module "react-avatar-editor"{
export import AvatarEditorProps = __ReactAvatarEditor.AvatarEditorProps;
export import AvatarEditor = __ReactAvatarEditor.AvatarEditor;
}
declare module "react-avatar-editor/AvatarEditor"{
export import AvatarEditor = __ReactAvatarEditor.AvatarEditor;
export default AvatarEditor;
}
And use it by:
import AvatarEditor from 'react-avatar-editor/AvatarEditor';
The Origin Code construtor:
enter image description here
but while I run the project, it fail to compile and show me an error:
./src/components/DealPic.tsx
Module not found: Can't resolve 'react-avatar-editor/AvatarEditor' in 'C:\Users\xiaomin\Desktop\React\inter-provincial-portrait\src\components'
Typescript v2.5.3 React v16
I had the same problem. To fix it install with npm this package in this format
npm install --save react-avatar-editor #types/react-avatar-editor

moment-duration-format.d.ts Definition Not Extending Moment Module

Any idea why this doesn’t work or how I can extend the duration interface to support the format function?
declare module 'moment' {
interface Duration {
format(template: string, precision?: string, settings?: any): string;
}
}
when used as:
moment.duration(minutes, 'minutes').format('mm');
I’m getting the error that ‘format' does not exist on type ‘Duration'
First, install types:
npm install --save-dev #types/moment-duration-format
Second, import them in your file:
/// <reference path='../..your-path.../node_modules/#types/moment-duration-format/index.d.ts' />
import * as moment from 'moment';
import 'moment-duration-format';
Then you can use
moment.duration(minutes, 'minutes').format('mm');
Imports:
import * as moment from 'moment';
import 'moment-duration-format';
Outside of your class, define the interfaces:
interface Duration extends moment.Duration {
format: (template?: string, precision?: number, settings?: DurationSettings) => string;
}
interface DurationSettings {
forceLength: boolean;
precision: number;
template: string;
trim: boolean | 'left' | 'right';
}
Then in your code:
const duration = moment.duration(minutes, 'minutes') as Duration;
return duration.format('mm');
If you defined your Duration interface in another file, you will need to export and import it as well.
You need to have the following dependencies installed:
"dependencies": {
"#types/moment-duration-format": "2.2.2",
"moment": "2.24.0",
"moment-duration-format": "2.3.2"
}
If that's the case then you need these imports in the exact same order:
import * as moment from 'moment';
import 'moment-duration-format';
Afterwards you should be able to do this:
const seconds: number = Math.floor(process.uptime());
const formatted: string = moment.duration(seconds, 'seconds').format({
precision: 0,
template: 'y [years], w [weeks], d [days], h [hours], m [minutes], s [seconds]',
});
you should use namespace instead of module
declare namespace moment {
interface Duration {
format(template: string, precision?: string, settings?: DurationSettings): string;
}
}
and settings for "moment-duration-format": "^2.3.2"
interface DurationSettings {
trim: boolean | 'left' | 'right';
useGrouping: boolean;
usePlural: boolean;
useLeftUnits: boolean;
precision: number;
useSignificantDigits: boolean;
trunc: boolean;
forceLength: boolean;
minValue: number;
maxValue: number;
largest: number;
}

Getting error can not compile module unless --module flag is provided. so not able to create instance of this class in another ts file

export module FilterBar {
export class Filter {
objData: any;
distinctAreas: string[];
distinctRegions: string[];
distinctSubRegions: string[];
distinctAreasApplied: string[];
distinctRegionsApplied: string[];
distinctSubRegionsApplied: string[];
call = 0;
static selectedFilterData: any;
}
I want to create an object of this class in another typescript file. For that I am using export to module but I am getting the mentioned error.

Categories

Resources