MagerX
MagerX
Explore posts from servers
TTCTheo's Typesafe Cult
Created by MagerX on 10/23/2024 in #questions
Vercel Deployment failing on fresh create-next-app, no logs outside of saying public folder empty
https://github.com/codymurphyjones/bubble-experiments This is the repo that I am trying to deploy, all I did was run npx create-next-app and follow the prompt and try to deploy it. Is there a step I'm missing that has been added or is something wrong? I configured the repo in vercel to be a nextjs app but it was not able to auto detect it successfully.
2 replies
TTCTheo's Typesafe Cult
Created by MagerX on 3/13/2024 in #questions
Fresh Create-t3-app isn't deploying to vercel
https://github.com/codymurphyjones/create-t3-issue I kept it as simple as possible, ran create-t3-app with typescript and app router and trpc. However whenever I deploy its unable to detect framework and isn't deploying any static assets other than favicon
26 replies
TTCTheo's Typesafe Cult
Created by MagerX on 1/20/2024 in #questions
Error: A previously unvisited boundary must have exactly one root segment.
Simulator/index.tsx
export default async function SimulatorParent() {
// const waitTime = await wait(10000);
// console.log("The promise", waitTime);
return (
<main className="flex flex-1 bg-gray-800 h-full">
<div className="flex flex-1 bg-gray-800 h-full">
<Suspense fallback={<div className="flex w-full h-full bg-red-500" />}>
<Simulator />
</Suspense>
</div>
</main>
);
}
export default async function SimulatorParent() {
// const waitTime = await wait(10000);
// console.log("The promise", waitTime);
return (
<main className="flex flex-1 bg-gray-800 h-full">
<div className="flex flex-1 bg-gray-800 h-full">
<Suspense fallback={<div className="flex w-full h-full bg-red-500" />}>
<Simulator />
</Suspense>
</div>
</main>
);
}
app/page.tsx
async function MainMenuSkeleton() {
return (
<>
<Link className="flex items-center justify-center" href="#">
<Image height={40} width={40} src="logo.svg" alt="logo" />
</Link>
<nav className="ml-auto flex gap-4 sm:gap-6">
...
</nav>
</>
);
}

async function MainMenu() {
return (
<>
<Link className="flex items-center justify-center" href="#">
<Image height={40} width={40} src="logo.svg" alt="logo" />
<span className="ml-2 text-xl font-bold">Dark Almanac</span>
</Link>
<nav className="ml-auto flex gap-4 sm:gap-6">
<Link
className="text-sm font-medium hover:underline underline-offset-4"
href="#"
>
About
</Link>
<Link
className="text-sm font-medium hover:underline underline-offset-4"
href="#"
>
Articles
</Link>
<Link
className="text-sm font-medium hover:underline underline-offset-4"
href="/login"
>
Login
</Link>
</nav>
</>
);
}

export default async function Component() {

return (
<div className="dark flex flex-col min-h-screen bg-gray-900 text-white">
<header className="px-4 lg:px-6 h-14 flex items-center">
<Suspense fallback={<MainMenuSkeleton />}>
<MainMenu />
</Suspense>
</header>

<SimulatorComponent />
<footer className="flex flex-col gap-2 sm:flex-row py-6 w-full shrink-0 items-center px-4 md:px-6 border-t border-gray-800">
<p className="text-xs text-gray-500">
© 2024 Game Theory Craft. All rights reserved.
</p>
<nav className="sm:ml-auto flex gap-4 sm:gap-6">
<Link className="text-xs hover:underline underline-offset-4" href="#">
About Us
</Link>
<Link className="text-xs hover:underline underline-offset-4" href="#">
Contact
</Link>
<Link className="text-xs hover:underline underline-offset-4" href="#">
Privacy Policy
</Link>
</nav>
</footer>
</div>
);
}
async function MainMenuSkeleton() {
return (
<>
<Link className="flex items-center justify-center" href="#">
<Image height={40} width={40} src="logo.svg" alt="logo" />
</Link>
<nav className="ml-auto flex gap-4 sm:gap-6">
...
</nav>
</>
);
}

async function MainMenu() {
return (
<>
<Link className="flex items-center justify-center" href="#">
<Image height={40} width={40} src="logo.svg" alt="logo" />
<span className="ml-2 text-xl font-bold">Dark Almanac</span>
</Link>
<nav className="ml-auto flex gap-4 sm:gap-6">
<Link
className="text-sm font-medium hover:underline underline-offset-4"
href="#"
>
About
</Link>
<Link
className="text-sm font-medium hover:underline underline-offset-4"
href="#"
>
Articles
</Link>
<Link
className="text-sm font-medium hover:underline underline-offset-4"
href="/login"
>
Login
</Link>
</nav>
</>
);
}

export default async function Component() {

return (
<div className="dark flex flex-col min-h-screen bg-gray-900 text-white">
<header className="px-4 lg:px-6 h-14 flex items-center">
<Suspense fallback={<MainMenuSkeleton />}>
<MainMenu />
</Suspense>
</header>

<SimulatorComponent />
<footer className="flex flex-col gap-2 sm:flex-row py-6 w-full shrink-0 items-center px-4 md:px-6 border-t border-gray-800">
<p className="text-xs text-gray-500">
© 2024 Game Theory Craft. All rights reserved.
</p>
<nav className="sm:ml-auto flex gap-4 sm:gap-6">
<Link className="text-xs hover:underline underline-offset-4" href="#">
About Us
</Link>
<Link className="text-xs hover:underline underline-offset-4" href="#">
Contact
</Link>
<Link className="text-xs hover:underline underline-offset-4" href="#">
Privacy Policy
</Link>
</nav>
</footer>
</div>
);
}
converting simulator/index.tsx into "use client" allows it to render without error but shows a yellow underline saying its a server render function and it shouldnt be on client side basically Console Output from next run dev
✓ Compiled / in 4.3s (587 modules)
⨯ Internal error: Error: A previously unvisited boundary must have exactly one root segment. This is a bug in React.
at aM (C:\Users\mager\Documents\Projects\dark-almanac\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:57694)
...
⨯ Error: failed to pipe response
at Q (C:\Users\mager\Documents\Projects\dark-almanac\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:394090)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
...
[cause]: Error: A previously unvisited boundary must have exactly one root segment. This is a bug in React.
at aM (C:\Users\mager\Documents\Projects\dark-almanac\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:57694)
....
}
○ Compiling /_error ...
✓ Compiled /_error in 1757ms (726 modules)
✓ Compiled / in 4.3s (587 modules)
⨯ Internal error: Error: A previously unvisited boundary must have exactly one root segment. This is a bug in React.
at aM (C:\Users\mager\Documents\Projects\dark-almanac\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:57694)
...
⨯ Error: failed to pipe response
at Q (C:\Users\mager\Documents\Projects\dark-almanac\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:394090)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
...
[cause]: Error: A previously unvisited boundary must have exactly one root segment. This is a bug in React.
at aM (C:\Users\mager\Documents\Projects\dark-almanac\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:57694)
....
}
○ Compiling /_error ...
✓ Compiled /_error in 1757ms (726 modules)
4 replies
TTCTheo's Typesafe Cult
Created by MagerX on 1/17/2024 in #questions
Section tag wont cover the entire container height
<main class="flex-1 bg-gray-800 h-full">
<section class="bg-gray-800 h-full">
<div id="test" class="flex justify-between">
<div class="bg-[#FF0000] w-1/3 m-2">
<b>Class Selector/Perks</b>
<div class="flex bg-green-800 h-1/2 w-full"></div>
</div>
<div class="bg-[#FF0000] w-1/3 m-2">
...
</div>
</div>
<div class="bg-[#FF0000] w-1/3 m-2">
<span class="p-1 bg-green-800">Details</span>
<span class="p-1 bg-orange-200">Physical Damage</span>
<span class="p-1 bg-blue-300">Magical Damage</span>
<div class="flex bg-green-800 h-full w-full"></div>
</div>
</div>
</section>
</main>
<main class="flex-1 bg-gray-800 h-full">
<section class="bg-gray-800 h-full">
<div id="test" class="flex justify-between">
<div class="bg-[#FF0000] w-1/3 m-2">
<b>Class Selector/Perks</b>
<div class="flex bg-green-800 h-1/2 w-full"></div>
</div>
<div class="bg-[#FF0000] w-1/3 m-2">
...
</div>
</div>
<div class="bg-[#FF0000] w-1/3 m-2">
<span class="p-1 bg-green-800">Details</span>
<span class="p-1 bg-orange-200">Physical Damage</span>
<span class="p-1 bg-blue-300">Magical Damage</span>
<div class="flex bg-green-800 h-full w-full"></div>
</div>
</div>
</section>
</main>
I am trying to create an interface that covers the entire viewport, however the section tag, despite having h-full is only covering about 50%-60% of the total height leaving a large open area at the bottom of the screen. Any ideas what I'm doing wrong that is preventing this element from filling its entire container? Here is the live example showing the issue: https://www.darkalmanac.com/builds
5 replies
TTCTheo's Typesafe Cult
Created by MagerX on 9/25/2023 in #questions
in the context of websockets is the UPGRADE request redundant now?
https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism#upgrading_to_a_websocket_connection i was interested in using the base web sockets and going through the motions of implementing this protocol but after reading more about it, it seems that it already occurs in the websocket api, so its not necessary to do myself? If I did want to do websockets from scratch, where would I start outside the websocket api?
1 replies
TTCTheo's Typesafe Cult
Created by MagerX on 7/24/2023 in #questions
Need help with dynamically typed rest parameters
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

type LastOf<T> =
UnionToIntersection<T extends any ? () => T : never> extends () => (infer R) ? R : never;

type Merge<A, B> =
{ [K in keyof A]: K extends keyof B ? B[K] : A[K] } & B extends infer O ? { [K in Exclude<keyof O, keyof A>]: O[K] } : never;

type ValueOf<T> = T[keyof T];

type StateOf<T> = T extends StateSlice<any, infer S> ? S : never;

class StateSlice<T, K extends { [key: string]: T }> {
constructor(public state: K) {}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
mergeStates<T extends StateSlice<any, any>>(
...slices: T[]
): StateSlice<ValueOf<Merge<StateOf<LastOf<T>>, UnionToIntersection<StateOf<T>>>>, Merge<StateOf<LastOf<T>>, UnionToIntersection<StateOf<T>>>> {
const newState = Object.assign(
{},
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return
...slices.map((slice) => slice.state)
) as Merge<StateOf<LastOf<T>>, UnionToIntersection<StateOf<T>>>;
return new StateSlice(newState);
}


trim(keys: (keyof K)[]): StateSlice<T, Pick<K, (typeof keys)[number]>> {
const newState = keys.reduce(
(state, key) => ({ ...state, [key]: this.state[key] }),
{} as Pick<K, (typeof keys)[number]>
);
return new StateSlice(newState);
}

append<J extends string, V>(
key: J,
value: V
): StateSlice<T | V, K & { [P in J]: V }> {
return new StateSlice({ ...this.state, [key]: value });
}

split(
keys: (keyof K)[]
): [
StateSlice<T, Pick<K, (typeof keys)[number]>>,
StateSlice<T, Omit<K, (typeof keys)[number]>>
] {
const includedState = this.trim(keys).state;
const excludedState = Object.keys(this.state)
.filter((key) => !keys.includes(key as keyof K))
.reduce(
(state, key) => ({ ...state, [key]: this.state[key as keyof K] }),
{} as Omit<K, (typeof keys)[number]>
);
return [new StateSlice(includedState), new StateSlice(excludedState)];
}
}

function createStateSlice<T, K extends { [key: string]: T }>(
initialState: K
): StateSlice<T, K> {
return new StateSlice(initialState);
}

const UserSignIn = createStateSlice({
username: "",
password: "",
});

const UserPreferences = createStateSlice({
displayName: "",
email: "",
});

const UserPreferences2 = createStateSlice({
firstName: "",
lastName: "",
confirmPassword: "",
});

const UserSignUp = UserSignIn.mergeStates(UserPreferences, UserPreferences2);
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

type LastOf<T> =
UnionToIntersection<T extends any ? () => T : never> extends () => (infer R) ? R : never;

type Merge<A, B> =
{ [K in keyof A]: K extends keyof B ? B[K] : A[K] } & B extends infer O ? { [K in Exclude<keyof O, keyof A>]: O[K] } : never;

type ValueOf<T> = T[keyof T];

type StateOf<T> = T extends StateSlice<any, infer S> ? S : never;

class StateSlice<T, K extends { [key: string]: T }> {
constructor(public state: K) {}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
mergeStates<T extends StateSlice<any, any>>(
...slices: T[]
): StateSlice<ValueOf<Merge<StateOf<LastOf<T>>, UnionToIntersection<StateOf<T>>>>, Merge<StateOf<LastOf<T>>, UnionToIntersection<StateOf<T>>>> {
const newState = Object.assign(
{},
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return
...slices.map((slice) => slice.state)
) as Merge<StateOf<LastOf<T>>, UnionToIntersection<StateOf<T>>>;
return new StateSlice(newState);
}


trim(keys: (keyof K)[]): StateSlice<T, Pick<K, (typeof keys)[number]>> {
const newState = keys.reduce(
(state, key) => ({ ...state, [key]: this.state[key] }),
{} as Pick<K, (typeof keys)[number]>
);
return new StateSlice(newState);
}

append<J extends string, V>(
key: J,
value: V
): StateSlice<T | V, K & { [P in J]: V }> {
return new StateSlice({ ...this.state, [key]: value });
}

split(
keys: (keyof K)[]
): [
StateSlice<T, Pick<K, (typeof keys)[number]>>,
StateSlice<T, Omit<K, (typeof keys)[number]>>
] {
const includedState = this.trim(keys).state;
const excludedState = Object.keys(this.state)
.filter((key) => !keys.includes(key as keyof K))
.reduce(
(state, key) => ({ ...state, [key]: this.state[key as keyof K] }),
{} as Omit<K, (typeof keys)[number]>
);
return [new StateSlice(includedState), new StateSlice(excludedState)];
}
}

function createStateSlice<T, K extends { [key: string]: T }>(
initialState: K
): StateSlice<T, K> {
return new StateSlice(initialState);
}

const UserSignIn = createStateSlice({
username: "",
password: "",
});

const UserPreferences = createStateSlice({
displayName: "",
email: "",
});

const UserPreferences2 = createStateSlice({
firstName: "",
lastName: "",
confirmPassword: "",
});

const UserSignUp = UserSignIn.mergeStates(UserPreferences, UserPreferences2);
Argument of type 'StateSlice<unknown, { firstName: string; lastName: string; confirmPassword: string; }>' is not assignable to parameter of type 'StateSlice<unknown, { displayName: string; email: string; }>'.
Type '{ firstName: string; lastName: string; confirmPassword: string; }' is missing the following properties from type '{ displayName: string; email: string; }': displayName, emailts(2345)
const UserPreferences2: StateSlice<unknown, {
firstName: string;
lastName: string;
confirmPassword: string;
}>
Argument of type 'StateSlice<unknown, { firstName: string; lastName: string; confirmPassword: string; }>' is not assignable to parameter of type 'StateSlice<unknown, { displayName: string; email: string; }>'.
Type '{ firstName: string; lastName: string; confirmPassword: string; }' is missing the following properties from type '{ displayName: string; email: string; }': displayName, emailts(2345)
const UserPreferences2: StateSlice<unknown, {
firstName: string;
lastName: string;
confirmPassword: string;
}>
{ firstName: string; lastName: string; confirmPassword: string; } is not assignable to parameter of type { displayName: string; email: string; } It's basically telling me that UserPrefernces2 isnt the exact same as UserPreferences and therefore an error. Is there anyway for me to dynamicly type ...rest parameters without losing typesaftey or throwing an error?
2 replies
TTCTheo's Typesafe Cult
Created by MagerX on 7/23/2023 in #questions
enum-union readme review and critique
Hey Guys, I released this little neat enum library a few days ago and posted it into r/typescript and cloud digest messaged me saying the really enjoyed the idea of the library and wanted to feature it on their newsletter which was cool. I was just hoping I could get some feedback on the readme so that way if there are any glaring holes that could complicate understanding for someone I can address it today. https://github.com/codymurphyjones/enum-union
2 replies
TTCTheo's Typesafe Cult
Created by MagerX on 7/22/2023 in #questions
Opinion on DX of this code, is it too confusing or easy to grasp?
const roles = makeEnum("User", "Admin", "Owner"); // Type: "User", "Admin", "Owner"
export type Roles = ExtractEnumType<typeof roles>; // "User" | "Admin" | "Owner"
export const Roles = TrimEnum(roles);


const [IRoles, iroles] = makeEnum("User", "Admin", "Owner"); // Type: "User", "Admin", "Owner"
export type IRoles = ExtractEnumType<typeof iroles>; // "User" | "Admin" | "Owner"
export{ IRoles };
const roles = makeEnum("User", "Admin", "Owner"); // Type: "User", "Admin", "Owner"
export type Roles = ExtractEnumType<typeof roles>; // "User" | "Admin" | "Owner"
export const Roles = TrimEnum(roles);


const [IRoles, iroles] = makeEnum("User", "Admin", "Owner"); // Type: "User", "Admin", "Owner"
export type IRoles = ExtractEnumType<typeof iroles>; // "User" | "Admin" | "Owner"
export{ IRoles };
Just wanted to get some second opinions on a fun library I'm working on. I'm reaching a point where typescript limitations are making me have to do strange patterns to get my desired behavior, so I want to try to pick a variation of it that resonates with other people and not just myself. As of the moment these are the only 2 that I could imagine, but if anyone has an idea on another way that I could return a type value/object and export them so that they appear as the same type. Additionally, is it safe to say that the top version is the more 'normal' version and the bottom one is definitely more react-like because of the array destrucuring or is that something common in all of javascript?
4 replies
TTCTheo's Typesafe Cult
Created by MagerX on 7/21/2023 in #questions
Opinions on code style preference in a library project I'm working on for enum replacements
So for the sake of boredom and seeing a lot of content related to enums lately pop up, I asked myself. "Hey, can I make a better version of enums?" And the truth is, I have no idea but its been an interesting journey to try to figure out. The bulk of the idea is fleshed out for my generative enums and the final step is probably adding support for custom object shapes rather than a transformative string or incremental index. However before that, I was just wondering if I could get some thoughts on preference in code style, especially in a library aiming to replace something as simple and concise as enum.
export const Roles = Enum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = Extract<typeof Roles>; // 0 | 1 | 2
export const Roles = Enum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = Extract<typeof Roles>; // 0 | 1 | 2
export const Roles = makeEnum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = ExtractEnumType<typeof Roles>; // 0 | 1 | 2
export const Roles = makeEnum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = ExtractEnumType<typeof Roles>; // 0 | 1 | 2
export const Roles = makeEnum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = ExtractEnum<typeof Roles>; // 0 | 1 | 2
export const Roles = makeEnum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = ExtractEnum<typeof Roles>; // 0 | 1 | 2
export const Roles = Enum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = Enum<typeof Roles>; // 0 | 1 | 2
export const Roles = Enum(3, "User", "Admin", "Owner"); // Type: { User: 0, Admin: 1 , Owner: 2 }
export type Roles = Enum<typeof Roles>; // 0 | 1 | 2
How do I weight the benefits and drawbacks of convenient naming versus more descriptive naming? Also added disclaimer, I understand that I am probably not replacing enums for anybody else in the world, but I was bored and thought it would be a fun project and I'm actually a huge fun of the results given that my types are unions and my intellisense still operates flawlessly I'm kind of leaning toward the last option but I am really curious the direction others would take
2 replies
TTCTheo's Typesafe Cult
Created by MagerX on 7/19/2023 in #questions
How to create dynamic number union in typescript
Hey guys, so I'm starting to think this isn't even possible (especially with the comments chatGPT added saying its not possible lol) so basically I have a function, which im going to call 'test' test receives a generic that is expected to be a union type. We will call this type R For the return type of 'test', it is sending back a tuple. This tuple consists of 2 objects of 2 different types. [R, X] Essentially, I need help solving for X. I need X to be a union type of numbers starting at 0 and incrementing until the length of the unions are equal. Is there any way to potentially accomplish this? It is in essence the final thing I need to complete the little project I've been working on today which is just a 'better' enum
type Role = 'User' | 'Admin' | 'Owner';
type RoleNum = 0 | 1 | 2;

//In the first example here, we are defining a 'Role' type and a generic R. Ideally we would be able to break down the union type passed into R to create the 'RoleNum' type. Instead of parameters, the data is passed in directly as the type.
function test<R extends string>(): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}



//In this example, we nix the R type all together and pass in the hard coded string values. This could be better because it includes an array that can be iterated through
function test(...role: string[] ): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}
type Role = 'User' | 'Admin' | 'Owner';
type RoleNum = 0 | 1 | 2;

//In the first example here, we are defining a 'Role' type and a generic R. Ideally we would be able to break down the union type passed into R to create the 'RoleNum' type. Instead of parameters, the data is passed in directly as the type.
function test<R extends string>(): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}



//In this example, we nix the R type all together and pass in the hard coded string values. This could be better because it includes an array that can be iterated through
function test(...role: string[] ): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}
13 replies
TTCTheo's Typesafe Cult
Created by MagerX on 7/8/2023 in #questions
Should I condense my hooks output array?
Hey guys, so I have my useValidation function and it returns the following array.
return [sync, isPropertyValid, watch, update, focus];
return [sync, isPropertyValid, watch, update, focus];
So 5 items in the array, but it seems like generally speaking the first 2 are the ones most frequently used like so
export default function Home() {
const [syncInput, isPropertyValid] = useValidation(AccountValidation);

return (
<>
<input
{...syncInput("username")}
style={{
border: !isPropertyValid("username")
? "thick double red"
: "thick double rgba(0,0,0,0)",
}}
type={"text"}
placeholder={"Enter your name"}
/>
</>
);
}
export default function Home() {
const [syncInput, isPropertyValid] = useValidation(AccountValidation);

return (
<>
<input
{...syncInput("username")}
style={{
border: !isPropertyValid("username")
? "thick double red"
: "thick double rgba(0,0,0,0)",
}}
type={"text"}
placeholder={"Enter your name"}
/>
</>
);
}
Should I condense my 5 item array into something smaller like this
const actions = {watch, update, focus}

return [sync, isPropertyValid, actions];
const actions = {watch, update, focus}

return [sync, isPropertyValid, actions];
Or do you think its better to leave it as 5?
24 replies
TTCTheo's Typesafe Cult
Created by MagerX on 6/26/2023 in #questions
Derive Type from Parameter of function attach to object (possibly recursive idk)
Hey Guys, so to explain what I'm doing, I'm basically defining a data structure to plug into a function of mine. The data structure is a key value and a class object that is defined on the fly. Like this
const AccountValidation: ValidationShape = {
username: Validation.new('').length(5),
password: Validation.new('').length(5)
}
const AccountValidation: ValidationShape = {
username: Validation.new('').length(5),
password: Validation.new('').length(5)
}
The Validation.new() function is used to define the default value for each field and instantiate an object to build my validation strategy.
type ValidationShape = {
[key: string ]: Validation<unknown>
}
type ValidationShape = {
[key: string ]: Validation<unknown>
}
This is the ValidationShape type and here is the Validation object class
export class Validation<T> {
default: T;
ValidationQueue: ValidationMethod[] = [];

constructor(val: T) {
this.default = val;
}

length(min: number, max?: number) {
this.ValidationQueue.push({
method: 'length',
min,
max

})
return this;
}

getDefaultValue(): T {
return this.default;
}

getValidationQueue(): ValidationMethod[] {
return this.ValidationQueue;
}

static new<T>(val: T) {
return new Validation(val);
}
export class Validation<T> {
default: T;
ValidationQueue: ValidationMethod[] = [];

constructor(val: T) {
this.default = val;
}

length(min: number, max?: number) {
this.ValidationQueue.push({
method: 'length',
min,
max

})
return this;
}

getDefaultValue(): T {
return this.default;
}

getValidationQueue(): ValidationMethod[] {
return this.ValidationQueue;
}

static new<T>(val: T) {
return new Validation(val);
}
So this is the object attached to each invidual key fpr my ValidationShape object. Now, I would like to take this shape, iterate over it and get the default value and its type and then take those values to create a new shape that is the key: ReturnType<GetDefaultValue>
type Reshape = {
[Property in keyof ValidationShape]: ReturnType<Property['getDefaultValue']>
}


const T: Reshape = {
username: "usernme",
password: "passwrd",
}
type Reshape = {
[Property in keyof ValidationShape]: ReturnType<Property['getDefaultValue']>
}


const T: Reshape = {
username: "usernme",
password: "passwrd",
}
Notice the reshape version is now just strings, since each new call was called with an empty string.
3 replies
TTCTheo's Typesafe Cult
Created by MagerX on 3/28/2023 in #questions
is there any way to redirect to the default 404 page after your search query on the server component
export async function generateMetadata(
pageProps: PageProps
): Promise<Metadata> {
const page = await getPageData(pageProps);
return { title: page?.name ?? "Unable to find page" };
}

export default async function Home(pageProps: PageProps) {
const pageData = await getPageData(pageProps);
console.log("page", pageData);

if (!pageData) {
return new Response("No data found", {
status: 404,
});
}
export async function generateMetadata(
pageProps: PageProps
): Promise<Metadata> {
const page = await getPageData(pageProps);
return { title: page?.name ?? "Unable to find page" };
}

export default async function Home(pageProps: PageProps) {
const pageData = await getPageData(pageProps);
console.log("page", pageData);

if (!pageData) {
return new Response("No data found", {
status: 404,
});
}
Im not in a position where i dont want to build a custom 404 page because I have a lot more work to do, but essentially i need some form of method to redirect to nextjs 13 404 page when the slug doesnt match anything in my sluglist
3 replies
TTCTheo's Typesafe Cult
Created by MagerX on 3/15/2023 in #questions
tailwind css hide divide when wrapping to new line
6 replies
TTCTheo's Typesafe Cult
Created by MagerX on 3/13/2023 in #questions
Recommendation on the tailwind pattern to style this footer gracefully
8 replies
TTCTheo's Typesafe Cult
Created by MagerX on 3/11/2023 in #questions
nextjs 13 eslint not flagging empty button type or poor indentation
1 replies
TTCTheo's Typesafe Cult
Created by MagerX on 3/6/2023 in #questions
Getting issues with navigation added to next13 layout
9 replies