Why is AVPlayerViewControllerAnimationCoordinator generating an undeclared type error? - avplayerviewcontroller

Why is AVPlayerViewControllerAnimationCoordinator generating an undeclared type error? As far as I can tell the method below is just a delegate method of AVPlayerViewController.
And yes I did import AVKit. Auto Complete wouldn't work on the method but I pasted it in directly from the docs.
extension SWVideoPlayerVC: AVPlayerViewControllerDelegate {
override func playerViewController(_ playerViewController: AVPlayerViewController, willTransitionToVisibilityOfTransportBar visible: Bool, with coordinator: AVPlayerViewControllerAnimationCoordinator) {
}
}

It’s only available on tvOS 11+ doc

Related

Unable to get type-safety (CustomTypeOptions) working with react-i18next

I recently successfully implemented using react-18next for localization needs inside my app. I have a small package that contains the localization files, react-i18next setup, and exports a class which is referenced in another application to get the i18n instance and pass it to the which wraps my components.
This has been deployed and works as expected.
I stumbled upon the documentation here (https://react.i18next.com/latest/typescript#create-a-declaration-file), which says that you are able to make the t function fully type safe. I would love to implement this, so that I am able to catch mis-matched key errors at compilation time, rather than needing to hunt for each case within the application.
I am having some trouble achieving this desired type-safety though, and wasnt sure if it was something that I am doing wrong or possibly a bug in the typing (I assume the former, as others seem to get the safety working without any issue).
Versions:
react-i18next “^11.15.6”
i18next “^21.6.14”
react “16.14.0”
typescript 4.1+
Repo structure (excluding package.json, tsconfig.json, etc) :
src
translations
translations_en.json
translations_es.json
MyTranslationManager.ts
react-i18next.d.ts
The translation files do not use any nested strings, and are separated by language (”_en” vs “_es”). Each language has all the needed strings in their localized format. The files are in this format:
{
"string1": "First string",
"string2": "Second string"
}
In my live (working) setup, this is how I initialize my instance:
import translationEN from "./translations/translations_en.json";
export class MyTranslationManager {
private readonly i18nInstance: i18nType;
constructor() {
this.i18nInstance = i18n.createInstance();
const defaultResources = {
en: { translation: { ...translationEN } },
};
this.language = "en";
this.i18nInstance
.use(initReactI18next)
.init({
resources: defaultResources,
lng: "en",
keySeparator: false, // we do not use nested translation resources
interpolation: {
escapeValue: false, // React already prevents XSS
},
});
}
// WORKING ON TYPE SAFETY
As directed in the docs, I create a react-i18next.d.s file to redeclare the “react-i18next” module - specifically the CustomTypeOptions interface:
import "react-i18next";
import translationEN from "./translations/translations_en.json";
declare module "react-i18next" {
interface CustomTypeOptions {
resources: typeof translationEN;
}
}
I do not declare a “defaultNS” option to CustomTypeOptions because I rely on the default namespace, “translation”.
When I attempt to compile the project with the above code, I get the following TS2344 issue:
node_modules/react-i18next/ts4.1/index.d.ts:203:25 - error TS2344:
Type 'string' does not satisfy the constraint 'Namespace<"btn_cancel" | "btn_save" | ... 86 more ... | "msg_unsavedChanges">'.
203 N extends Namespace = DefaultNamespace,
The error is thrown from each line in react-i18next/ts4.1/index.d.ts that attempts to set Namespace = DefaultNamespace.
I copied over as much of the code in index.d.ts as I could into the Typescript playground to try and get some insight into what is happening here, and I am able to get the compilation error to repro.
Hovering over the following items in the Typescript playground gives some interesting insight:
DefaultResources will resolve to { “btn_cancel”: string; “btn_ok”: string; }
DefaultNamespace will resolve to “ type DefaultNamespace<T = "translation"> = T extends "btn_cancel" | "btn_ok" ? T : string “
I assume this gets set by the use of the Fallback type, which gets passed in each key from DefaultResources via the keyof...
Link to playground.
My question is, why are the keys for the language files being set as the namespace? Is this by design? Am I importing the resources in an incorrect manner?
I noticed that the example here (https://github.com/i18next/react-i18next/blob/master/example/react-typescript4.1/no-namespaces/%40types/react-i18next/index.d.ts) only shows what the docs point to as an older version, i.e using the DefaultResources type instead of CustomTypeOptions. Any guidance on using the new method without namespaces would be greatly appreciated :)
For anyone working with i18next#v22.0.0 and react-i18next#v12.0.0, following the documentation here was successful for me (as of the time this was posted):
https://www.i18next.com/overview/typescript
I am now getting types for my translations inside of the t() function

Swift 4.1.2 Autocomplete: Suggesting extensions on Array that it shouldn't

Maybe I'm going crazy here, but extension Array where Element == String in Swift 4.1.2 is exposing its properties in Swift's autocomplete on types when it should not be there.
For example, this extension:
extension Array where Element == String {
public var test: [String] {
return ["test"]
}
}
Then start typing:
[123].te ...
and Swift suggests that the test property is also available on [Int] which is impossible. Then the syntax checker pops up the error:
Type of expression is ambiguous without more context
Is there something I'm missing? Perhaps some other/additional conformance restrictions that need to be used? Or is this a Swift bug?
It appears to be a bug.
This Swift.org bug report demonstrates the same behavior:
https://bugs.swift.org/browse/SR-5388

Importing namespace and interface with methods in TypeScript (TSX) in pdfjs-dist (PDFJS)

I am trying to use pdfjs-dist in my React project, but get a lot of problems trying to import the module and the functions in the project.
The pdfjs-dist module index.d.ts in #types/node_modules is defined so that it contains a namespace "PDF" and a module "pdfjs-dist" which exports "PDF".
The file has interfaces, which contains methods such as "getDocument(name:string)" which I want to call from my other classes.
In short; the file consists of a lot of interfaces and methods that are implemented through this interface, on the form:
declare module "pdfjs-dist" {
export = PDF;
}
declare namespace PDF {
interface PDFJSStatic {
getDocument(
source: string,
pdfDataRangeTransport ? : any,
passwordCallback ? : (fn: (password: string) => void, reason: string) => string,
progressCallback ? : (progressData: PDFProgressData) => void): PDFPromise < PDFDocumentProxy > ;
}
I have tried to use the regular import statements, such as:
import * as PDF from "pdfjs-dist"
and
import { PDFJSStatic } from "pdfjs-dist"
However, it does not seem to respond very well. VS Code gives me all the interfaces, so I can see what they are, but this is where my knowledge of React and Typescript falls a bit short.
How would I go about calling the methods and actually using the "getDocument()" method?
For some reason the fix seems to be to import the interface first, so that the PDFJSStatic and other interfaces are available when using the require statement on line 2.
The import statements that I used were;
import { PDFJSStatic, PDFPageProxy } from "pdfjs-dist";
let PDFJS: PDFJSStatic = require("pdfjs-dist");
This is probably not the correct way of doing it, but it works.

Typescript Class.prototype.MyFunction makes errors but working

I can't explain why I get an error but code works. Is that compiler bug? (I use Visual Studio Code with Angular 2)
class A
{
fun(a: number)
{
return a+2;
}
}
A.prototype.F = function() { return "F here!"+this.fun(1); } // This makes error: The property 'F' does not exist on value of type 'A'
var a: A = new A();
console.log(a.F());
And bonus: This is not working at all! (no access to this.fun())
A.prototype.F2 = () => { return "F2 here!"+this.fun(1); } // ()=>{} is not working! cause _this is not defined!
...
console.log(a.F2());
Edit #1
As #seangwright said I need to use Module Augmentation but...
As far as it's working with simple example with my A class I can't make it work with Angular's ComponentFixture. This should solve my problem if I do this like in Typescript example:
declare module '#angular/core/testing' // I was trying without this line and with 'global' instead of '#angular/core/testing' but nothing helps
{
interface ComponentFixture<T>
{
TestOf(cssSelector: string): string;
}
}
But I still get an error:
'ComponentFixture' only refers to a type, but is being used as a value
here.'
at this point:
ComponentFixture.prototype.TextOf = function(cssSelector: string): string
{
...
}
There is even more errors, for example when I try to use it:
let fixture: ComponentFixture<EditableValueComponent>;
fixture = TestBed.createComponent(EditableValueComponent);
I got:
'ComponentFixture' is not assignable to type
'ComponentFixture'. Two different types with
this name exist, but they are unrelated. Property 'TestOf' is
missing in type 'ComponentFixture'
So again: Code works but has many compilation errors. Or maybe I'm missing something obvious?
I get the feeling you are a C# developer based on how you format your code.
Part 1
In Typescript once you declare your class, the type system expects it to have the properties (shape) you define and that's it.
The more of the type system you want to use, the less dynamic your objects will/can be.
That said, the reason your code runs (transpiles) correctly is because this is an error in the context of Typescript's structural type system, not Javascript's dynamic type system. So Typescript will tell you A doesn't have a property F at compile time, but Javascript doesn't care that it's added at runtime.
One solution is to merge the class with an interface
class A {
fun(a: number) {
return a + 2;
}
}
interface A {
F(): string;
}
A.prototype.F = function () { return "F here!" + this.fun(1); }
var a: A = new A();
console.log(a.F());
Another would be to temporarily abandon the type system
class A {
fun(a: number) {
return a + 2;
}
}
(A.prototype as any).F = function () { return "F here!" + this.fun(1); }
var a: A = new A();
console.log((a as any).F());
But that becomes verbose and prone to errors and loses the benefits that a type system brings.
You mention you are using Typescript with Angular 2. You could write in ES2015 if you wanted a more dynamic syntax. But then you will lose some of the benefits that Angular 2 gets from using Typescript (better tooling, smaller deployments).
Part 2
The reason your second example doesn't work at all has nothing to do with Typescript and everything to do with Scope (or execution context) in Javascript, specifically ES2015 arrow functions.
An arrow function does not create its own this context, so this has its original meaning from the enclosing context.
Unlike in your first example you are not using the traditional function declaration syntax and instead are using the () => {} arrow function syntax. With your first example
A.prototype.F = function() { return "F here!"+this.fun(1); }
this refers to whatever context F() is going to be executing in. Since you define it on the prototype of A it is going to be executing in the context of A. A has a .fun() method so this.fun() is going to be the same one defined in your class above.
With your second example, F2 is not going to be executing in the context of A despite being defined as a method of its prototype. The arrow function syntax is instead going to allow F2 to run in the context of the enclosing context which is the global window object unless you are running in strict mode in which case
in browsers it's no longer possible to reference the window object through this inside a strict mode function.
So this will be undefined and calling fun() on undefined is going to throw an error.
Try adding a console.log(this) to your F2 function.
A.prototype.F2 = () => { console.log(this); return "F2 here!"+this.fun(1); }
When you run the transpiled Javascript you will probably see Window logged out to the console, and then probably an error like Uncaught TypeError: _this.fun is not a function
Use the Typescript Playground to write some Typescript, see what the tooling tells you, what transpiled Javascript is created and then run it to see if your Javascript is correct.

Iterating over module exports with implicit any

So I'm writing a module with sub-modules for angular. Notation:
module App.services {
export class SomeService { }
}
and I initialize all services using:
function defToArray(def: any): any[] {
return (def.dependencies || []).concat(def)
}
for (var s in App.services)
app.service(s, defToArray(App.services[s]));
However defToArray(App.services[s]) causes "Index signature of object type implicitly has an 'any' type".
I already tried casting like defToArray(<any>App.services[s]) and defToArray(App.services[s] as any), but no luck.
Any thoughts?
Casts are not very tightly binding.
Instead of
defToArray(<any>App.services[s])
try
defToArray((<any>App.services)[s])
or if you prefer
defToArray((<{[key:string]:any}>App.services)[s])
For clarification, the goal here is not to cast the type of App.services[s], you're actually trying to provide type information for the access-by-index operator. This is only an issue when noImplicitAny is enabled (but IMO it always should be, so it's just one of the things you learn to adjust to)

Resources