Internet. Long-time listener, blah blah blah.
I've got a React app using Typescript. I've got a function in one file that accepts a limited range of strings, and a function in a different file that calls that thing. I was ready to move on this morning when I realized that - duh - this is probably a perfect opportunity to do some type-checking, improving stability going forward.
Since then, I've been slowly losing my mind. There's something important I'm missing, but no amount of reading or randomly combining types and interfaces has gotten me any closer. Any help is appreciated.
ForestPage:
toggle = (e: any) => {
const target = e.currentTarget.dataset.toggletarget;
Tree.toggle(target);
}
Tree:
type cart = "elm" | "oak" | "pine";
type Itoggle = (target: cart) => void;
const toggle: Itoggle = (target: cart) => {
console.log('Now toggling', target);
}
The catch here is that ForestPage can pass any string whatsoever, and everything will proceed just fine. What is "cart" doing, if not establishing a type?
I started putting this into Code Snippet, but it didn't seem to have the proper libraries (including TypeScript), and this post is already two pages and it's 4:00 on a Friday.
The code above is the simplest version of my code. I've also tried a variety of other options.
https://www.tutorialsteacher.com/typescript/typescript-interface
type cart = "elm" | "oak" | "pine";
interface Itoggle = {
(target: cart) : void
}
const realToggle = (target: cart) => {
console.log(target);
}
const toggle: Itoggle = realToggle;
First, tsLint changed Itoggle from an interface back to a type, on its own. Then, the results were unchanged - I can still pass in any value to target.
How to require a specific string in TypeScript interface
This where I learned that 'type cart' could replace 'enum cart'.
https://medium.com/@KevinBGreene/typescript-enums-and-polymorphism-with-type-matching-fc3dc74b031c
enum cart = elm, oak, pine;
interface elm {
target: cart.elm
}
interface oak {
target: cart.oak
}
type targetType = elm | oak
const toggle = (target: targetType) => {
console.log(target)
}
I think I had this working, but I needed to have
console.log(target.target.target)
which is obviously stupid.
const toggle = (target: cart) => {
errored out. I'm afraid I don't remember exactly how, but think it was something to do with the fact that enums are innately of type {[key: string]: number}, and I was just sending a string.
https://2ality.com/2020/01/typescript-enums.html#use-case%3A-safer-string-constants
Changed the enum from before to:
enum cart {
elm: "elm",
oak: "oak",
pine: "pine"
}
but it still wanted to be fed some kind of object, and it was looking increasingly unlikely, anyway.
https://thoughtbot.com/blog/booleans-and-enums
Useful article about enums, but it said nothing about parameters. I abandon looking at enums, pretty sure I'm barking up the wrong tree. Back to types.
But, but... they should work, right? https://www.typescriptlang.org/docs/handbook/enums.html
I also tried experimenting with generating new types and enums on the fly, based on available data, but that made the linter break down. Which, I guess, makes sense. It's not built at the point that it needs to be read.
interface pleaseWork {};
const options = ["elm", "oak", "pine"];
_.each(options, (option) => {
pleaseWork[option] = option... etc, etc
Various varieties therein, of course, none of which were any good. Again, logically, that makes some sense. But I was cracking by this point.
At any rate, any guidance is appreciated. I've looked at it long enough that nothing makes sense anymore, and I don't feel like I'll make progress without at least a gentle shove in the right direction.