You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DynamoDB is a NoSQL database which allows you to work with JSON documents. Every database item has a primary key, and any number of attributes. The JSON documents must follow the following format:
awaitdynamodb.putItem({// Some string attributes.id: {S: "user_123"},name: {S: "Cristian"},// A list of strings.colors: {SS: ["red","blue"]},// A number. It can hold up to 38 digits so in JS it may need the use of bigint.age: {N: "34"},// A boolean.isAdult: {B: "true"},// A date timestamp.createdAt: {N: "601858800000"},// A string date.deletedAt: {S: "1989-01-28T00:00:00.000Z"},});
As you can see, the attribute type is defined by the key of the object and the values are mostly represented as strings. Retrieving items from DynamoDB will use the same format. This means that, in order to work with these items, some data conversions may be necessary, such as:
constitem=awaitdynamodb.getItem({id: {S: "user_123"}});constage=Number(item.age.N);// or BigInt(item.age.N)constisAdult=item.isAdult.B==="true";constcreatedAt=newDate(Number(item.createdAt.N));constdeletedAt=newDate(item.deletedAt.S);
These conversions can be tedious and error-prone, but can be alleviated with the help of a type system such as TypeScript.
// We can define a type for the DynamoDB item.declareconstdynamodb: DynamoDB<{item: {id: string;name: string;colors: Color[];age: StringEncoded<bigint>;isAdult: "true"|"false";createdAt: StringEncoded<Timestamp>;deletedAt: StringEncoded<Date>;};}>;// And some helper functions to convert the DynamoDB item to our type.declarefunctionbigIntFromString(s: StringEncoded<bigint>): bigint;declarefunctionbooleanFromString(s: "true"|"false"): boolean;declarefunctiondateFromTimestamp(s: StringEncoded<Timestamp>): Date;declarefunctiondateFromString(s: StringEncoded<Date>): Date;constitem=awaitdynamodb.getItem({id: {S: "user_123"}});// It's now trivial to work with the item.constage=bigIntFromString(item.age.N);constisAdult=booleanFromString(item.isAdult.B);constcreatedAt=dateFromTimestamp(item.createdAt.N);constdeletedAt=dateFromString(item.deletedAt.S);
Writing items can also take advantage of the type system:
awaitdynamodb.putItem({// This will fail because "not a number" is not a StringEncoded<bigint>age: {N: "not a number"},// ^^^^^^^^^^^^^^ Error: Type string is not assignable to StringEncoded<bigint>.// Whereas this will work.age: {N: stringEncode(34n)},});
Type safety can further be improved by using opaque types. Let's say we're working with different type of IDs:
// By using opaque types, the type system will prevent us from mixing them up.typeUserId=OpaqueType<string,{readonlyt: uniquesymbol}>;typeBlogId=OpaqueType<string,{readonlyt: uniquesymbol}>;declareasyncfunctioncreateBlogEntry(userId: UserId,blogId: BlogId,blogEntry: string): Promise<void>;// ...declareconstuserId: UserId;declareconstblogId: BlogId;createBlogEntry(blogId,userId,"hello world!");// ^^^^^^ Error: Type 'BlogId' is not assignable to type 'UserId'.
Conclusion
Winglang would benefit a lot from a type system similar to TypeScript: a structural type system with type inference, generics, and opaque types. This would allow for a more robust and type-safe codebase, and would make it easier to work with external APIs such as DynamoDB.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
DynamoDB is a NoSQL database which allows you to work with JSON documents. Every database item has a primary key, and any number of attributes. The JSON documents must follow the following format:
As you can see, the attribute type is defined by the key of the object and the values are mostly represented as strings. Retrieving items from DynamoDB will use the same format. This means that, in order to work with these items, some data conversions may be necessary, such as:
These conversions can be tedious and error-prone, but can be alleviated with the help of a type system such as TypeScript.
Writing items can also take advantage of the type system:
Type safety can further be improved by using opaque types. Let's say we're working with different type of IDs:
Conclusion
Winglang would benefit a lot from a type system similar to TypeScript: a structural type system with type inference, generics, and opaque types. This would allow for a more robust and type-safe codebase, and would make it easier to work with external APIs such as DynamoDB.
Some native types would be very welcome:
JsonSerializable
JsonEncoded<T>
jsonEncode<T extends JsonSerializable>(data: T): JsonEncoded<T>
Stringifiable
StringEncoded<T>
stringEncode<T extends Stringifiable>(data: T): StringEncoded<T>
opaque<T>
Beta Was this translation helpful? Give feedback.
All reactions