Nominal types versus structural types is basically the main distinction at this point (if we ignore .net, etc). I like both languages, happy to see them converge while keeping their defining characteristics
They aren't structural because the following doesn't work in C#, but would work (with tweaks to make it valid code) in a structurally typed language such as TypeScript:
var transformed = media.Select(m => {
var parts = m.Split('/');
return new {
addedAtUtc = "2023-05-15T05:59:31.398Z",
originTripUid = parts[4],
path = $"{parts[4]}/{parts[5]}",
rank = "",
size = 103978,
stored = true,
type = "document",
};
}).ToList();
transformed.AddRange(otherMedia.Select(m => {
var parts = m.Split('/');
return new {
addedAtUtc = "2023-05-15T05:59:31.398Z",
originTripUid = parts[4],
path = $"{parts[4]}/{parts[5]}",
rank = "",
size = 103978,
stored = true,
type = "document",
documentType = parts[6]
};
}));
Adding "documentType" breaks in C# but would work in a structurally typed language as a structural type checker can see that the second result fulfills all of the necessary properties. Doing this in C# would require creating an interface and being explicit.
Sure, but that would be opt-in if it were ever implemented. I think both styles of type system have their pros and cons. I have loved the cross-pollination between C# and TS with great ideas flowing in both directions.
I get that; that's why I qualified it as a "functional perspective" because even though the underlying implementation is an auto-generated, auto-named type, the functional usage of it is a structural type (with limitations).
Your list of differences is correct but not really what I meant. The points you listed are mostly due to JS runtime constraints. The choice of nominative vs structural type system is purely a design choice by the typescript team.