Maximum call stack size exceeded when using the new typescript enabled version of reactjs - reactjs

I use the new typescript supported version of reactjs
along with the redux-orm and when u try to insert a value into the store i get this issue of "Maximum call stack size exceeded" the same works with the old template
Below is the code with new typescript supported reactjs which throws the error
https://reactjs.org/docs/static-type-checking.html#typescript and the old github version https://github.com/microsoft/TypeScript-React-Starter which works.
https://drive.google.com/open?id=15eolNjeYroyubgSmbGaaKfjxbe-IZ8KK
I am unable to understand what is different that causes the error with the new version. Thanks for any help.

Properties can't be defined directly on Model classes.
The root cause lies in the create-react-app's babel preset - transpilation output introduces additional property descriptors in Model prototype chain.
These properties interfere with descriptors installed by redux-orm during schema registration, resulting in Maximum call stack size exceeded error.
This can be avoided through declaration merging, specifically by providing a class and an interface with matching names. The interface contains Model properties, the class is almost 1:1 to JS Model definition.
Example:
interface Book {
id: number
title: string
}
class Book extends Model<typeof Book> {
static modelName = 'Book' as const
static fields = {
id: attr(),
title: attr()
}
}
I've created a repo with working example: https://github.com/tomasz-zablocki/redux-orm-ex-types-react-example
Mind you, these are custom types, but it's definitely where I'd like to take the #types/redux-orm package to, likely with the 0.14 release of redux-orm.

Related

How can i create a custom object in Salesforce with a '__' in the name?

I am trying to check if a change tables exists in Salesforce by calling
var name = "acme_npsp__Allocation_c__c";
try
{
salesforceObject = _service.describeSObject(name);
return sObject;
}
catch (Exception ex)
{
error = ex.Message;
}
but it gives an error:
INVALID_TYPE: salesforceObject type 'acme_npsp__Allocation_c__c' is not
supported. If you are attempting to use a custom object, be sure to append the
'__c' after the entity name. Please reference your WSDL or the describe call for
the appropriate names.
(107 - FIELD_INTEGRITY_EXCEPTION) Cannot create a new component with the namespace: acme_npsp. Only components in the same namespace as the organization can be created through the API.
But if i replace the __ in the middle with a single _ it seems to work , but that isnt my object in salesforce so i cant reference it in other code.
Salesforce doesnt allow to create such an object with '__' in the middle, but it was created using the package Nonprofit Success Pack (NPSP) which can be downloaded from the store.
How can i create the object with the '__' in the middle , ie after the npsp ?
Salesforce does not allow __ in API names, because double underscores serve a special meaning: they delimit the components of the API name. An API name, for a schema element like this, consists of up to 3 parts:
namespace__component_name__c
namespace is the first component, and is the (optional) namespace, which indicates that the component is part of a package. NPSP's namespace is npsp. You cannot create components in a namespace you do not own.
The name element is present on all components. For Account and other standard objects, it's the entire API name.
__c is the suffix, which indicates what kind of entity you have. __c is a custom object; __b a BigObject; __e a custom Platform Event; __mdt a custom Metadata Type. Lack of a suffix indicates a standard component.
Your question does not make much sense as written. You appear to be trying to work with the object npsp__Allocation__c. It's not clear why you are trying to prepend some other value to the namespace and suffix.
Accessing the describe does not create an object, so the behavior of your code is exactly as designed.

Unable to get type-safety (CustomTypeOptions) working with react-i18next

I recently successfully implemented using react-18next for localization needs inside my app. I have a small package that contains the localization files, react-i18next setup, and exports a class which is referenced in another application to get the i18n instance and pass it to the which wraps my components.
This has been deployed and works as expected.
I stumbled upon the documentation here (https://react.i18next.com/latest/typescript#create-a-declaration-file), which says that you are able to make the t function fully type safe. I would love to implement this, so that I am able to catch mis-matched key errors at compilation time, rather than needing to hunt for each case within the application.
I am having some trouble achieving this desired type-safety though, and wasnt sure if it was something that I am doing wrong or possibly a bug in the typing (I assume the former, as others seem to get the safety working without any issue).
Versions:
react-i18next “^11.15.6”
i18next “^21.6.14”
react “16.14.0”
typescript 4.1+
Repo structure (excluding package.json, tsconfig.json, etc) :
src
translations
translations_en.json
translations_es.json
MyTranslationManager.ts
react-i18next.d.ts
The translation files do not use any nested strings, and are separated by language (”_en” vs “_es”). Each language has all the needed strings in their localized format. The files are in this format:
{
"string1": "First string",
"string2": "Second string"
}
In my live (working) setup, this is how I initialize my instance:
import translationEN from "./translations/translations_en.json";
export class MyTranslationManager {
private readonly i18nInstance: i18nType;
constructor() {
this.i18nInstance = i18n.createInstance();
const defaultResources = {
en: { translation: { ...translationEN } },
};
this.language = "en";
this.i18nInstance
.use(initReactI18next)
.init({
resources: defaultResources,
lng: "en",
keySeparator: false, // we do not use nested translation resources
interpolation: {
escapeValue: false, // React already prevents XSS
},
});
}
// WORKING ON TYPE SAFETY
As directed in the docs, I create a react-i18next.d.s file to redeclare the “react-i18next” module - specifically the CustomTypeOptions interface:
import "react-i18next";
import translationEN from "./translations/translations_en.json";
declare module "react-i18next" {
interface CustomTypeOptions {
resources: typeof translationEN;
}
}
I do not declare a “defaultNS” option to CustomTypeOptions because I rely on the default namespace, “translation”.
When I attempt to compile the project with the above code, I get the following TS2344 issue:
node_modules/react-i18next/ts4.1/index.d.ts:203:25 - error TS2344:
Type 'string' does not satisfy the constraint 'Namespace<"btn_cancel" | "btn_save" | ... 86 more ... | "msg_unsavedChanges">'.
203 N extends Namespace = DefaultNamespace,
The error is thrown from each line in react-i18next/ts4.1/index.d.ts that attempts to set Namespace = DefaultNamespace.
I copied over as much of the code in index.d.ts as I could into the Typescript playground to try and get some insight into what is happening here, and I am able to get the compilation error to repro.
Hovering over the following items in the Typescript playground gives some interesting insight:
DefaultResources will resolve to { “btn_cancel”: string; “btn_ok”: string; }
DefaultNamespace will resolve to “ type DefaultNamespace<T = "translation"> = T extends "btn_cancel" | "btn_ok" ? T : string “
I assume this gets set by the use of the Fallback type, which gets passed in each key from DefaultResources via the keyof...
Link to playground.
My question is, why are the keys for the language files being set as the namespace? Is this by design? Am I importing the resources in an incorrect manner?
I noticed that the example here (https://github.com/i18next/react-i18next/blob/master/example/react-typescript4.1/no-namespaces/%40types/react-i18next/index.d.ts) only shows what the docs point to as an older version, i.e using the DefaultResources type instead of CustomTypeOptions. Any guidance on using the new method without namespaces would be greatly appreciated :)
For anyone working with i18next#v22.0.0 and react-i18next#v12.0.0, following the documentation here was successful for me (as of the time this was posted):
https://www.i18next.com/overview/typescript
I am now getting types for my translations inside of the t() function

Get Class Name of Class Subclassing Array in TypeScript?

I have the following class (ported from JavaScript wherein this works [prior to adding the types]) within TypeScript:
class A extends Array {
private _foo: string;
constructor(settings: any) {
super();
this._foo = 'foo';
}
get Foo() {
return (this._foo);
}
set Foo(value) {
this._foo = value;
}
}
let test = new A({ });
test.push('1');
test.push(2);
test.push('3');
// outputs "A" in JavaScript
// outputs "Array" in TypeScript
console.log(test.constructor.name);
The issue is outlined at the bottom of the code snippet, I'm expecting to get the class name back from test.constructor.name of "A" but am instead getting "Array". It seems like in the specific case of subclassing Array objects, TypeScript blows away the constructor name. Is there a way to find the class name within TypeScript which doesn't rely upon .constructor.name?
This happens because you have es5 as a target in compilerOptions and Typescript polyfills class
Have a look at generated code for es5 vs ES2015.
If you don't need to support really old browsers you can safely use a higher target than es5
I've tested your code in the Playground here
And it correctly outputs "A". I suspect something else is going on, possibly with your build tools or config.
I would suggest trying to use just tsc to narrow down the problem. If tsc correctly outputs, you can then move on to any other plugins, or build steps

Create an array of objects using the class generated by Core Data in XCode 8

I'm struggling a little with how XCode 8 and Swift 3 manage classes in Core Data.
I have an entity that I've created, called PersonMO (the 'MO' standing for 'Model Object'). My understanding is that building my project after creating this entity results in a Class Definition being created elsewhere.
If I try to create an array of objects using that class definition, I get an error.
var people:[PersonMO] = [
PersonMO(age:"24", firstName: "Cassie", isVisited: false, lastName: "Brist", locationCity: "San Francisco", locationState: "CA", notes: "none", phoneNumber: "000-0000", zone: "9")
]
The error is "Cannot invoke initializer for type 'PersonMO' with an argument list of type 'arguments listed here'", which makes sense because I never initialized the people array with default values.
Prior to XCode 8 and Swift 3, I had a Person.swift file that I initialized my values in, but now that XCode creates the class elsewhere, if I try to initialize in that file, I get an "Invalid redeclaration of 'PersonMO'" error.
How can I create a hard-coded array of objects in XCode 8 and Swift 3?
Your issue has got nothing to do with generated classes. To create a NSManagedObject (assuming you have a ready setup NSPersistentContainer):
var people:[PersonMO] = []
persistentContainer.performBackgroundTask { (moc: NSManagedObjectContext) in
//create new MO
let newPersonMo = PersonMO(context: moc)
// set attributes
newPersonMo.name = "Peter"
//add it to your array
people.append(newPersonMo)
//save
do {
try newPersonMo.managedObjectContext?.save()
} catch {
print("failed to save with error: \(error)")
}
}
Independent of your issue, you can choose if and what Xcode is creating for your entities whithin your Models Inspector:
I recommend to set CodeGen to Class Definition.
Note: to make this work without issues (I assume an Apple bug), the Module field has to be empty ("Global namespace" in light gray).
Starting with iOS 10, there is now NSManagedObject.init(context:) initializer you can use, instead of init(entity:insertInto:). It's an extension that Apple has created for simplifying object creation. But you still need to use this initializer instead of your own.
The designated initializer of managed objects is init(entity:insertInto:). You should not be initializing managed objects using different initializers.
From Apple's documentation:
A managed object is associated with an entity description (an instance of NSEntityDescription) that provides metadata about the object (including the name of the entity that the object represents and the names of its attributes and relationships) and with a managed object context that tracks changes to the object graph. It is important that a managed object is properly configured for use with Core Data. If you instantiate a managed object directly, you must call the designated initializer (init(entity:insertInto:)).

can we edit the definitely typed file in typescript to change some parameter types?

Can we edit definitely typed file in Typescript?
When using ui-grid with typescript I came across a scenario where I edited the
ui-grid.d.ts file to make the date filter work. I need to filter the date based on the displayed result in the ui-grid and not on the
raw data (the data which I am getting from the Web API).
Here is the code snippet:
ui-grid.d.ts file code:(under interface IFilterOptions)
condition?: number;
Corresponding typescript code:
column.filter = {
condition: (searchTerm, cellValue, row, column) => {
var date = this.$filter("date")(row.entity.Date, this.masks.date.angular)
return (date + '').toLowerCase().indexOf(searchTerm.toLowerCase().replace(/\\/g, "")) !== -1;
}
}
The error I faced is as follows:
Type '(searchTerm:any, cellValue:any, row:any, coloumn:any) => boolean' is not assignable to type 'number'
After that I made the changes to the filter object to return a number as follows:
column.filter = {
condition: (searchTerm, cellValue, row, column) => {
var date = this.$filter("date")(row.entity.Date, this.masks.date.angular)
var res: number = (date + '').toLowerCase().indexOf(searchTerm.toLowerCase().replace(/\\/g, "")) !== -1 ? 1 : 0;
return res;
}
}
But after this I got error saying that:
Type '(searchTerm:any, cellValue:any, row:any, coloumn:any) => number' is not assignable to type 'number'
After this I made the change in the definitely typed file i.e. in the ui-grid.d.ts file as follows:
under interface IFilterOptions
I changed
condition?: number;
to
condition?: (searchTerm: any, cellValue: any, row: any, column: any) => boolean | number;
so the corresponding filter function which worked for me is as follows:
column.filter = {
condition: (searchTerm, cellValue, row, column) => {
var date = this.$filter("date")(row.entity.Date, this.masks.date.angular)
return (date + '').toLowerCase().indexOf(searchTerm.toLowerCase().replace(/\\/g, "")) !== -1;
}
}
Is this the right way to solve this problem?
Can anyone guide me to the right solution if the above solution is not good or it is not a good practice to edit the definitely typed file?
And also used
column.filterCellFiltered = true;
instead of filter function but it didn't work. This is also a concern as why it didn't work because I need to filter the date based on the displayed result in the ui-grid and not on the raw data. Can anyone explain why it didn't work?
Please help me understand the right approach. Let me know if anyone require any other details. Thanks in advance.
Angular JS version: AngularJS v1.4.7
Angular JS definitely typed version : Angular JS 1.4+
ui-grid Version: * ui-grid - v3.0.5
ui-grid definitely typed version: ui-grid v3.0.3
typescript version: 1.0.3.0
i had also same problem ,
adding "< any >" beginning of the function should solve the problem.
like this :
condition: <any>((searchTerm, cellValue, row, column) =>
{
return cellValue.indexOf(searchTerm) > -1
})
and don't forget to parenthesis ().
You can, but the changes will be overwritten the next time you install/upgrade that dependency, and won't be reflected in git (assuming you're not checking generated files into source control). You're better off overriding the type definitions in your project. The common way to do this is within an #types directory but anywhere within your TS project will work.
You'll want to create a file with the extension .d.ts under TS's project files. The modules within this file will be merged with other declaration files, to determine the final type definition. So in your case you'd want:
// ui-grid.override.d.ts
declare module 'ui-grid' {
// overriden types go here
}
The benefit of this method is that you only need to add the types you want, and the rest will be merged with the definitely typed declarations.
This is a very useful tool if you need to do things like type globals, or to provide additional type information for libraries. It's used extensively in the definitely typed declarations for library plugins which alter an api in some way.
I'd recommend reading the TS docs on declaration files as they're an incredibly useful tool if used correctly.
Although if you do find the types in definitely typed are incorrect/incomplete then please create a PR for the benefit of everyone
I do not recommend to modify definitions and sources of the libraries you do not actively develop. What will happen when you will decide to upgrade to the newer version and it will override your changes? You will be forced to merge them each time you upgrade. And the larger your project will get the more complicated this will become.
I would recommend to either submit a request to the angular-ui team, or find a way to go with existing functionality.
Hope this helps.

Resources