Typewriter: generate TypeScript parameter properties - typewriter

Currently I am using Typewriter for automatic generation of TypeScript class from my C# classes. Lets say I have this very simple C# class:
[Dto]
public class MyDto
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
Also I have this simple typewriter template:
$Classes(c => c.Attributes.Any(x => x.Name == "Dto"))[
export class $Name {
constructor(
$Properties[
public $name: string,
]
) { }
}]
The issue I have with this template is that there is a trailing comma after the last constructor parameter property in the generated ts class:
export class MyDto {
constructor(
public prop1: string,
public prop2: string, /* <---- notice the comma here */
) { }
}
I would like to have the properties of the C# class generated as parameter properties in the TypeScript class, but with the example above the generated TypeScript is not valid. Is there a way to achieve this with a Typewriter template?

To answer my own question: I amended the template like this:
$Classes(c => c.Attributes.Any(x => x.Name == "Dto"))[
export class $Name {
constructor(
$Properties[
public $name: string][,]
) { }
}]

Related

How to define a private property when implementing an interface in Typescript?

I'm using TypeScript in my project and I have come across an issue.
I'm defining an interface like this:
interface IModuleMenuItem {
name: string;
}
I want to create a class that implements from this interface but I want the name to be a private property like this:
class ModuleMenuItem implements IModuleMenuItem {
private name: string;
}
I'm getting the following error:
Class ModuleMenuItem incorrectly implements interface IModuleMenuItem.
Property name is private in type ModuleMenuItem but not in type
IModuleMenuItem.
How can I define a property as private or protected when implementing an interface?
Interfaces define "public" contracts and as such it doesn't make sense to have protected or private access modifier on interfaces, which are more of a, let's call it, implementation detail. For that reason you can't do what you want with an interface.
If you want to make the property read-only to consumers, but overridable in a subclass then you can do something like this:
interface IModuleMenuItem {
getName(): string;
}
class ModuleMenuItem implements IModuleMenuItem {
private name;
public getName() {
return name;
}
protected setName(newName : string) {
name = newName;
}
}
I think in TypeScript 2.0 (not out yet) you will be able to use the readonly access modifier if you were after initialization-time readonly field - https://basarat.gitbooks.io/typescript/content/docs/types/readonly.html
interface IModuleMenuItem {
readonly name : string;
}
class ModuleMenuItem implements IModuleMenuItem {
public readonly name : string;
constructor() {
name = "name";
}
}
I think you may do it like this
interface IModuleMenuItem{
name: string
}
class ModuleMenuItem implements IModuleMenuItem {
private _name: string;
constructor() {
_name = "name";
}
get name(){
// your implementation to expose name
}
set name(value){
// your implementation to set name
}
}
In case of having private fields in class, you need to introduce setter and get methods for that field like so:
export class Model {
private _field: number;
get field(): number {
return this._field;
}
set field(value: number) {
this._field= value;
}
}
And then create the interface as usual (We can not use private modifier for interface fields) like so:
export interface IModel {
field: number;
}
Then implement it to our class like so:
export class Model implements IModel {
...
}
TypeScript will understand that this model is implemented correctly the interface as we have introduced set and get method.
The only way you can have an inner state and assign interface to that instead of class and make that state private
class A{
private state:IA = ...
}
As an addendum to Syntax's response, there is no need to include a setter. A getter method is all that is needed. This could be used, for example, for read-only variables set at initialization, though I suppose it's better to use the readonly modifier in this case.
interface IModuleMenuItem
{
name: string;
}
class ModuleMenuItem implements IModuleMenuItem{
private name$: string;
constructor(name: string)
{
this.name$ = name;
}
public get name()
{
return this.name$;
}
}
Use abstract classes instead.
Composition over inheritance.
interface AppInterface {
app: express.Application
port: string | number
}
abstract class AbstractApp implements AppInterface {
app: express.Application
port: string | number
constructor(){
this.app=express()
this.port=8080
}
protected defaultMiddlewares(): void {}
}
class App extends AbstractApp {
constructor() {
super()
}
protected defaultMiddlewares(): void {
this.app.use(express.json())
}
}

How to write angular filter definition in controller with typescript

I have following working code, its just that i am using javascript, want to convert it into full typescript code.
My html has div with ng-repeat with a filter definition, the definition is available on scope, as follows
<input type="text" ng-model="vm.searchText"/>
<div ng-repeat="item in vm.items | filter:vm.filterItems(vm.searchText)">{{item.name}}</div>
and the view's controller class has scope vm properties searchText, items and a filterItems(filter definition) as follows
export interface IMyScope extends ng.IScope
{
vm: MyController;
}
export class ItemClass {
private _name: string;
constructor(name: string) {
this._name = name;
}
public get name(): string {
return this._name;
}
}
export class MyController
{
private _searchText: string;
private _items: ItemClass[];
constructor(scope: IMyScope) {
scope.vm = this;
this._items = [];
this._items.push(new ItemClass("test1"));
this._items.push(new ItemClass("value2"));
this._items.push(new ItemClass("foo"));
}
public get searchText(): string {
return this._searchText;
}
public set searchText(value: string) {
this._searchText = value;
}
public get items(): ItemClass[] {
return this._items;
}
public filterItems(criteriaText: string) {
return function (item: ItemClass): boolean {
if (!criteriaText) {
return true;
}
return item.name.toLowerCase().indexOf(criteriaText.toLowerCase()) > -1;
}
}
}
I want to convert this filterItems in typescript,
Thanks in Advance
its just that i am using javascript, want to convert it into full typescript code.
I want to convert this filterItems in typescript,
What you have is already TypeScript. You can tell by the use of type annotations.

Serialize a derived class without access to base class

I need to serialize a derived class in my Windows Phone 7 Project for tombstoning state.
But I don't have access to the code to the base class - exposed by a Library -.
//don't have access to this class
public class A
{
public string member1 {get;set;}
}
[DataContract]
public class B : A
{
public B(){}; //CTOR
[DataMember]
public string member2 {get;set;}
}
When the system try to serialize (I save it to PhoneApplicationPage.State => so it's auto serializing) : it's not working, the exception (InvalidDataContractException) says "Type 'B' cannot inherit from a type that is not marked with DataContractAttribute or SerializableAttribute. Consider marking the base type 'A' with DataContractAttribute or SerializableAttribute, or removing them from the derived type."
Should I implement a custom serializer ? How can I do that (in Windows Phone 7)
Rather than derive from the library class, you could have a member variable that of that type and expose the properties of the library class member via custom getters and setters:
[DataContract]
public class MyClass
{
BaseClass Wrapped { get; set; }
public MyClass()
{
Wrapped = new BaseClass( );
}
[DataMember]
public string member1
{
get { return Wrapped.member1; }
set { Wrapped.member1= value; }
}
}

How to change exported property through MEF?

I'm studying MEF, and try to use Export attribute to export a property, and import it in an other class.
But my problem is that I want to change this property and the other class can import a new value.
For example,
[Export]
public class A{
[Import("Notes")]
public string Description{get;set;}
}
[Export]
public class B{
[Export("Notes")]
public string Text{get;set;}
}
I want once I change the Text of class B, the A.Description can get changed too.
So, how can I implement this?
Any good idea?
This approach would work for most reference type but not with string which is immutable. This means that after you change the value of B.Text, the objects referenced by A.Description and B.Text will no longer be the same (you can use Object.ReferenceEquals to test this).
One way to do what you are after using MEF is to export/import a method instead of the property:
[Export]
public class A
{
public string Description { get { return GetDescription(); } }
[Import("GetNotes")]
Func<string> GetDescription;
}
[Export]
public class B
{
public string Text { get; set; }
[Export("GetNotes")]
string GetText()
{
return Text;
}
}
Finally note that there are other ways to do this. The most common in .NET is with events.

AutoMapper Ignore an item in a collection based on a property value in the source

I'm mapping an ApplianceViewModel to a ApplianceDTO. Each Appliance has a collection of ActionViewModels which are mapped to ActionDTO. What I'd like to do is configure the mapper to ignore ActionViewModels whose IsPersisted value is False.
My ViewModel classes ...
public interface IApplianceViewModel : INotifyPropertyChanged
{
ObservableCollection<IActionViewModel> Actions { get; set; }
// other properties removed for simplicity
}
public interface IActionViewModel : INotifyPropertyChanged
{
bool IsPersisted { get; set; }
// other properties removed for simplicity
}
My DTO classes ...
public class ApplianceDTO
{
public IEnumerable<ActionDTO> Actions { get; set; }
// other properties removed for simplicity
}
public class ActionDTO
{
// properties removed for simplicity
}
I set up my mapping like this ...
Mapper.CreateMap<IApplianceViewModel, ApplianceDTO>();
Mapper.CreateMap<IActionViewModel, ActionDTO>()
var appliance = new ApplianceViewModel {
Actions = new ObservableCollection<IActionViewModel>(
new List<IActionViewModel> {
new ActionViewModel { IsPersisted = true },
new ActionViewModel { IsPersisted = false }
}};
var applianceDTO = Mapper.Map<IApplianceViewModel, ApplianceDTO>(applianceDTO);
Currently my applianceDTO will have two items in it's Actions collection, but I'd like to set up my mapping so that the ApplianceActionViewModel with the IsPersisted property set to false isn't mapped. Can I do this?
Update
Omu's comment lead me to a solution using a ValueResolver to map the collection of Actions. I'm not really happy with this solution but its the best option available.
First I created a custom ValueResolver.
public class IsPersistedCollectionResolver : ValueResolver<IApplianceViewModel, IEnumerable<ActionDTO>>
{
protected override IEnumerable<ActionDTO> ResolveCore(IApplianceViewModel source)
{
return Mapper.Map<IEnumerable<IActionViewModel>, IEnumerable<ActionDTO>>(source.Actions.Where(x => x.IsPersisted));
}
}
Then I modified my code to use it in the mapping configuration.
Mapper.CreateMap<IApplianceViewModel, ApplianceDTO>()
.ForMember(dest => dest.Actions, opt => opt.ResolveUsing<IsPersistedCollectionResolver>());
Mapper.CreateMap<IActionViewModel, ActionDTO>();
have you tried doing something like :
Mapper.map(objects.Where(o => o.IsPersisted == true))

Resources