[ Feature Request ] - FileSystem<T>
See original GitHub issueSuggestion
FileSystem<T> type
Works with alot of simplicity
- If it hits a folder adds it into the ‘object’ type and its children as traversable keys
- If it hits a file thats a module it adds whatever its typeof import(“…”) type would be.
- Recursive
Similar behavior to import(“…”) type. Usage: FileSystem<“…/static”>
FileSystem<"./api">
on this folder structure would produce the following object type which also shows how it would handle index.ts
- api
-users
- by-id.ts
- all.ts
- index.ts
-posts
- all.ts
type Result = {
users: {
by-id: typeof import("./api/users/by-id");
all: typeof import("./api/users/all");
} & typeof import("./api/users"),
posts: {
all: typeof import("./api/posts/all");
}
}
Use Cases and Examples
1: Every use case where previously people had alot of types or classes floating around and then had a single place where they imported all those types/classes into a union just to support typescript can now just use a folder to store those things in conjunction with FileSystem
// people using ORM's can avoid having a 'single' source where all their classes are imported in favor of just using a folder.
await database.user(123);
// folder strcuture
// tables
user.ts {default: class UsersTable { getUsers() { return [] }}} // contains following module
type ORM = {
[K in keyof FileSystem<"../tables">]: FileSystem<"../tables">][K]["default"]
}
declare const database: ORM ;
database.users.getUsers();
2: Really strong support for image paths, and removing files in refactors that are referenced by string path.
// (note: requires augmentation of JSX types);
<img src={"/static/dolphin.png"}/> // error dolphin.png isn't loaded in the file system.
3: Support for string based routing in applications and protection against routing refactors at a type-level.
// (note: requires augmentation of JSX types);
<a href={"/home/name"}/>
// currently people do something like this just to have 'route refactorability' which bloats bundle size.
const Routes = {
Home: {
name: "/home/name"
}
} as const
// can now do this..
- screens
- home
- name.ts // React page
4: Statically typed readFileSync for people using it to access their file system
const readFileSystem = (path: keyof FileSystem<".">): string=> fs.readFileSync(path);
5: Statically typed API handling
(pseudo code)
// before
const response = await api<typeof import("/api/user")>("/api/user")
// after
const response = await api.user(1);
// implementation
const api = new Proxy<FileSystem<"../../../api">>(...);
- Many more use cases (File system based redux, file system based statically typed ExpressJS etc)
Precedence: When people look at the implementation in the standard library they will notice FileSystem doesn’t have a implementation in the same way you can “peek definition” for types like Exclude
and Omit
, however there already is precedence for type-level helpers that work as a ‘compiler flag’ (I.E ThisType<T>
);
Also utilizes a lot of things that already exist like typeof import(“…”) functionality.
Previous issue: https://github.com/microsoft/TypeScript/issues/41550
Further important notes:
- People are going to want to type things with the ‘flattened’ keys of a FileSytem<T> in various formats which will easily be possible to use it in conjunction with existing mapped types and new string literal types.
- People are going to want to use FileSystem to represent things that are FileSystem’Like which again is easily possible with mapped/string literal
- People are going to want to use FileSystem to represent transformations that could happen at build time which is again possible with mapped/string literal types.
Checklist
My suggestion meets these guidelines:
- This wouldn’t be a breaking change in existing TypeScript/JavaScript code
- This wouldn’t change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript’s Design Goals.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:6
- Comments:10 (1 by maintainers)
Top GitHub Comments
I try not to say “never” on things that aren’t clearly out-of-scope, but the complexity issues here are massive since we’re dealing with the file system, which is much more than just a simple tree. Issues I would expect us to encounter immediately:
'index'
? Seems valid since there are not necessarily commonjs modulesFileSystem<notfoundpath>
an error, or a no-op? Either answer is going to surprise and annoy at least 30% of users and prompt a request for a commandline flag or other configuration path.A.ts
and you can havea.ts
and we’re both OK, but only one of us can be right on the type sideBasically the upside value here when compared to running an out-of-band tool to autogen a .d.ts file when the file layout changed would need to be very, very, very compelling for us to open the floodgates on the bug farm and configuration Rubik’s cube this would introduce.
As @pauldraper mentioned, the main request here is to have
Import
as a type that accepts a generic alongside theimport
keyword. I think, the FileSystem is a wrong name all together.