7 ms·
> With the ‘unknown’ type available is there a good case for ‘any’ anymore? Lets say you have some input json that you want to slightly modify to something els
by 9034725985 4y ago
> With the ‘unknown’ type available is there a good case for ‘any’ anymore?
Lets say you have some input json that you want to slightly modify to something else. How would you do this with unknown? I can't just blindly replace any with unknown. I'd get errors like this:
The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'unknown'.ts(2407)
For example, how can I do this better?
Remember the input json could be pretty much anything. I don't have a spec other than I only care about things that end with __c.
https://github.com/kusl/salesforcecontactmapper/blob/eff0b3eba893d562a002b9d85931524954de8171/src/main.ts#L4 https://github.com/kusl/salesforcecontactmapper/blob/eff0b3e...
import { Output } from "./Output";
import { Preference } from "./Preference";
export function MyMap(input: unknown): Output {
const mypreferences = Array<Preference>();
for (const prefCode in input) {
if (prefCode.endsWith("__c")) {
if (prefCode === "IsInternalUpdate__c") {
continue;
}
let currentValue = "";
if (input[prefCode] !== null) {
currentValue = input[prefCode].toString();
}
if (currentValue === "true") {
currentValue = "True";
}
if (currentValue === "false") {
currentValue = "False";
}
const preference: Preference = {
PrefCode: prefCode,
CurrentValue: currentValue
}
mypreferences.push(preference);
}
}
const myOutput: Output = {
ContactId: input.Contact__c,
Email: input.ContactEmail__c,
IsInternalUpdate: true,
Preferences: mypreferences
}
return myOutput;
}
- mxz3000 4y agowell you expect 'input' to be something that you can iterate over, so clearly using any is wrong here.
- 9034725985 4y agoyes, input is a json of some kind. You could say technically could be simply { "Unsubscribe__c": false } or even {} both of which are silly in my case because there is no key for me to identify who the person is but they are valid inputs. Or the test case I have is https://github.com/kusl/salesforcecontactmapper/blob/eff0b3eba893d562a002b9d85931524954de8171/test/input.json#L16 https://github.com/kusl/salesforcecontactmapper/blob/eff0b3e... Or the input could have a thousand key values and I only care about some of them. What should my object look like? How do I create a class that says everything that ends in "__c" is something I care about? I tried unknown. I tried Object. How do I fix this (and learn something so I fix all future code I write)?
- wizofaus 4y agoWhat's wrong with Object?
- 9034725985 4y agoIf I set input as Object, if (input[prefCode] !== null) { currentValue = input[prefCode].toString(); } in the lines above, I see a red underline under input[prefCode] > Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Object'. No index signature with a parameter of type 'string' was found on type 'Object'.ts(7053)
- wizofaus 4y agoCould you use a helper like function getProperty<T, K extends keyof T>(o: T, propertyName: K): T[K] { return o[propertyName]; } ?
- erur 4y agoYou can go incredibly far with the type system. If you wanna go down that rabbit hole, I'd suggest Typescript type challenges. Completely blew my mind when I came across it the first time. When you start out with typescript you might think Omit<> and Partial<> are cool but holy hell, you can do so much more.
- sarahdellysse 4y agoinput: Record<string, unknown>
- deleted 4y ago[deleted]
- 9034725985 4y agoThank you. That gives me a red underline under ContactId and Email now. I think because input.Contact__c and input.ContactEmail__c are unknown. I think this is the right direction. What is my next step? const myOutput: Output = { ContactId: input.Contact__c, Email: input.ContactEmail__c, IsInternalUpdate: true, Preferences: mypreferences } (property) Output.ContactId: string Type 'unknown' is not assignable to type 'string'.ts(2322) Output.ts(4, 5): The expected type comes from property 'ContactId' which is declared here on type 'Output'
- quickthrower2 4y agoNice I tbink that is the answer! It is for when the way you need to deal with the data is so dynamic and runtime specified that crafting out the interface/types to cast to would be painful to impossible. Data wrangling.
- manhinli 4y agoYou can do some pretty powerful stuff with TypeScript types, so you could model it like this: https://www.typescriptlang.org/play?#code/C4TwDgpgBAysBOBLAdgcwKLICYtQSWQFVCBhKAXigAMASAbwGcFcBfAfTYGMqBuAWABQg0JCgAFeBABmESck7RKdQVFXjJUkgHssEAFyxmaTDjQFiJHqoD01qADkAhvHhaA7rKgjowABaPgKE5fCE4AawZ1aW1dSOdoRwAbRKgIbFwoFCgAIg5ObJU1EgBXFzTgADUk4v0oJiQ0fgEWQWFwaAB5YuAwboooZQE1KG1kYEdOYDwsA3rcJuH0AFtHRETZo1QFtTwGAmBZZCTCMCwA2oAjLS1EiEdkbdUJaVk0hQYDZ5k5BQBtAF0mi0hAIUAd4FIJtAAIIMBjFJYQLAEXqBCAADwO2EiACVQlp4FgADxzNAAGigxWQYWQ7mQAD4BoVVKNxpM8hsGltmSMtGMJsBlqtEhy6psga0BFIqZNEHzUtjzKQABT1Tm4ACUnMykTgXJMuCVZEGw0kwFKyDF8AAdGksAwAOqIPzK3JcbIaiUgyWSjFgAmBaXyYByy0AWRAYccYGVKFRBlh8MRyOQqK1UC6PT6JrUnD5TCgS3AGle8ggkUo0JcjhARK+pYU9OVnslwykBKgyrzyALvzAGhiEAp-ekVUSNX+UC0UgzFwAVqFgLaxkhy7HU90NRqmUNhmpEDPlXa9kQVSPNDoIFud3vb5lD+fBxRyJRsrt9odjqdznkPTe7wB3YhsgNSPABUDAjyAG3IEnClHIlTVIoUDnmONQAPzWsAWh6rgzZQOh6E5NkTRQXeB6dnBZRjGhigvjkCA1H+ObgXuVEIbR-TZAAKvATFgQBkG7qxFFdvB5ScS+r6QokDAQMxZGsexElIVxABiSRySRil7kJrGqN2Bbng2tT1j8yEsfpTwDpeBiPpeZI6QBJTUYh461MpNFIU5ah6fpRbGeZDDWr0DC+MqgVvFeAm+TyfkGfmgRFpm8YZt0qL9JZwysgK0wGHG3TWjl7JcI5wl7kKaz5RuS7FYKKxrHkZUAe+YyfokJxnAcBiMUOOlmVFHyFsWLxBXFrZqGaFrDSl3RAkAA https://www.typescriptlang.org/play?#code/C4TwDgpgBAysBOBLAd...