I’m new to SPA and I’m learning it with durandal and breeze. Recently I have switched my solution to Typescript and I’m wondering is there any good solution to generate typed breeze entities in TypeScript basing on EF model on the server. Only thing I have found is this post Breeze.js typed entities but this is only small piece of code and not even a real project. I’m wondering is there any better solution to this issue?
-
We use typelite http://type.litesolutions.net/ which use t4 templates to generate typescript interfaces. It mostly works well. (Old question I konw) – mortb Mar 09 '16 at 08:46
1 Answers
Below is a page you can drop in your site to generate typescript interface definitions. The page fetches the breeze metadata then iterates through all of the types and outputs a typescript interface declaration for each type. The output of this page can then be pasted in any typescript file (*.ts) or typescript definition file (*.d.ts). Enclose the results in a module declaration if you want to namespace the interfaces: declare module northwind { ... paste interfaces here... }
.
Before using the page you'll need to make one edit: change the entity manager's controller url from "api/northwind" to whatever your breeze controller's url is.
The generated interfaces have a dependency on the Knockout.js typescript definitions which you can grab here: https://github.com/borisyankov/DefinitelyTyped/tree/master/knockout/
Using the northwind example from learn.breezejs.com, the output of this definitions generator page would be something like this:
export interface Employee extends breeze.Entity {
FirstName: KnockoutObservable<string>;
LastName: KnockoutObservable<string>;
}
you could then execute a query using breeze and cast the results to an array of employees like this:
var manager = new breeze.EntityManager('api/northwind');
var query = new breeze.EntityQuery()
.from("Employees");
manager.executeQuery(query).then(data => {
// ***cast the results to a strongly typed array of Employee***
var employees = <Employee[]>data.results;
}).fail(e => {
alert(e);
});
below is the definitions generator page- add a new html file to your project named "definitions.html", run the project and navigate to the page.
<html>
<head>
<title>Typescript Definition Generator</title>
<style>
code {
white-space: pre;
}
</style>
<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/q.js/1.0.0/q.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/breezejs/1.4.4/breeze.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var entityManager = new breeze.EntityManager('api/northwind');
entityManager.fetchMetadata()
.then(function () {
var html = '',
types = entityManager.metadataStore.getEntityTypes(),
type,
i,
j,
property,
crlf = String.fromCharCode(13),
code = document.createElement('code'),
script = document.createElement('script');
function getJSType(metadataType) {
if (/(Int64)|(Int32)|(Int16)|(Byte)|(Decimal)|(Double)|(Single)|(number)/.test(metadataType))
return 'number';
else if (/(DateTime)|(DateTimeOffset)|(Time)|(Date)/.test(metadataType))
return 'Date';
else if (/(Boolean)/i.test(metadataType))
return 'boolean';
return 'string';
}
for (i = 0; i < types.length; i++) {
// type declaration
var type = types[i];
html += 'export interface ' + type.shortName;
// base type
html += ' extends ';
if (type.hasOwnProperty('baseEntityType')) {
html += type.baseEntityType.shortName;
} else {
html += 'breeze.Entity';
}
html += ' {' + crlf;
// data properties
for (j = 0; j < type.dataProperties.length; j++) {
property = type.dataProperties[j];
if (type.baseEntityType && type.baseEntityType.dataProperties.filter(function (p) { return p.name === property.name; }).length > 0)
continue;
html += ' ' + property.name;
//if (property.isNullable)
// html += '?';
html += ': KnockoutObservable<';
html += getJSType(property.dataType.name);
html += '>; //' + property.dataType.name + crlf;
}
// navigation properties
for (j = 0; j < type.navigationProperties.length; j++) {
property = type.navigationProperties[j];
if (type.baseEntityType && type.baseEntityType.navigationProperties.filter(function (p) { return p.name === property.name; }).length > 0)
continue;
html += ' ' + property.name;
//if (property.isNullable)
// html += '?';
if (property.isScalar)
html += ': KnockoutObservable<';
else
html += ': KnockoutObservableArray<';
html += property.entityType.shortName;
html += '>;' + crlf;
}
html += '}' + crlf + crlf;
}
code.innerHTML = html;
$(code).addClass('prettyprint');
document.body.appendChild(code);
script.setAttribute('src', '//google-code-prettify.googlecode.com/svn/loader/run_prettify.js');
document.body.appendChild(script);
})
.fail(function (reason) {
alert(reason);
});
});
</script>
</head>
<body>
</body>
</html>

- 26,470
- 12
- 87
- 133
-
Tnx for help. I'm new to this technologies and I'm not sure how to use this code in my project? I have tried to add new html file to project and access it in runtime but nothing is generated. Can You help me how to use this code and preview generated entities? – dnf Mar 23 '14 at 17:33
-
I've updated the answer with a full html file you can drop into any site. – Jeremy Danyow Mar 23 '14 at 19:29
-
Now it woks ;) Tnx for sharing. If I may ask I’m now wondering how to translate query result from breeze to generated entities. I can copy field values but entity will be disconnected from breeze model? – dnf Mar 23 '14 at 19:39
-
I updated the answer with some details on how to use the generated interfaces. – Jeremy Danyow Mar 26 '14 at 20:31
-
Tnx for Your answer – i don’t even thought that simple cast will be enough ;) – dnf Mar 27 '14 at 09:01